指针解法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | 给定一个由 0 和 1 组成的数组arr,将数组分成 3个非空的部分 ,使得所有这些部分表示相同的二进制值。
如果可以做到,请返回任何[i, j],其中 i+1 < j,这样一来:
arr[0], arr[1], ..., arr[i]为第一部分;
arr[i + 1], arr[i + 2], ..., arr[j - 1]为第二部分;
arr[j], arr[j + 1], ..., arr[arr.length - 1]为第三部分。
这三个部分所表示的二进制值相等。
如果无法做到,就返回[-1, -1]。
注意,在考虑每个部分所表示的二进制时,应当将其看作一个整体。例如,[1,1,0]表示十进制中的6,而不会是3。此外,前导零也是被允许的,所以[0,1,1] 和[1,1]表示相同的值。
示例 1:
输入:arr = [1,0,1,0,1]
输出:[0,3]
示例 2:
输入:arr = [1,1,0,1,1]
输出:[-1,-1]
示例 3:
输入:arr = [1,1,0,0,1]
输出:[0,2]
提示:
3 <= arr.length <= 3 * 104
arr[i]是0或1
|
| class Solution:
def threeEqualParts(self, arr: List[int]) -> List[int]:
def find(x):
s = 0
for i, a in enumerate(arr):
s = s + a
if s == x:
return i
n = len(arr)
cnt, mod = divmod(sum(arr), 3)
if mod > 0:
return [-1, -1] # 如果1的总数不够整除直接返回false
if cnt == 0:
return [0, n-1] # 如果cnt为0,说明整个数组全部为0
# 分成3段,分别找到第一二三段的第一个1,i、j、k分别指向它们
i, j, k = find(1), find(cnt + 1), find(2*cnt + 1)
while k < n and arr[i] == arr[j] == arr[k]:
i = i + 1
j = j + 1
k = k + 1
return [i-1, j] if k == n else [-1, -1]
|
① i、j、k分别指向三段中第1个1
| 0 1 1 0 0| 0 1 1 0 0 0| 0 0 1 1 0 0
^ ^ ^
i j k
|
② i、j、k跳出循环
| 0 1 1 0 0| 0 1 1 0 0 0| 0 0 1 1 0 0
^ ^ ^
i j k
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k,
同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
示例 2:
输入:nums = [0,1,1]
输出:[]
解释:唯一可能的三元组和不为 0 。
示例 3:
输入:nums = [0,0,0]
输出:[[0,0,0]]
解释:唯一可能的三元组和为 0 。
|
leetcode792-匹配子序列的单词数
给定字符串 s和字符串数组words, 返回words[i]中是s的子序列的单词个数。
字符串的 子序列 是从原始字符串中生成的新字符串,可以从中删去一些字符(可以是none),而不改变其余字符的相对顺序。
例如, “ace” 是 “abcde” 的子序列。
示例 1:
输入: s = "abcde", words = ["a","bb","acd","ace"]
输出: 3
解释: 有三个是s 的子序列的单词: "a", "acd", "ace"。
Example 2:
输入: s = "dsahjpjauf", words = ["ahjpjau","ja","ahbwzgqnuk","tnmlanowax"]
输出: 2
提示:
1 <= s.length <= 5 * 104
1 <= words.length <= 5000
1 <= words[i].length <= 50
words[i]和 s都只由小写字母组成。
| class Solution:
def numMatchingSubseq(self, s: str, words: List[str]) -> int:
d = defaultdict(list)
res = 0
for w in words:
d[w[0]].append(w)
for c in s:
for _ in range(len(d[c])): ###>>>>这两需要配合保证3条,只弹出3次
w = d[c].pop(0) ###>>>>while循环会一直循环里面的东西为空
###例如:bb,弹出1次,之后紧接着又进入,在次弹出,这个时候c是没有变化的
if len(w) == 1:
res = res + 1
else:
d[w[1]].append(w[1:])
return res
|