1、滑动窗口要素
双向指针,条件判断,暴力求解
2、模板
3、实例
167. 两数之和 II - 输入有序数组
给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。
函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。
说明:
返回的下标值(index1 和 index2)不是从零开始的。 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 示例:
输入: numbers = [2, 7, 11, 15], target = 9 输出: [1,2] 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
题解:双向指针
一个指针指向开头,一个指针指向结尾,如果a[l]+a[r]==target,返回[l+1,r+1];如果a[l]+a[r]<target,l+=1;如果a[l]+a[r]>target,r+=1
def f(a,target):
l,r=0,len(a)-1
while(l<r):
s=a[l]+a[r]
if(s==target):
return [l+1,r+1]
elif(s<target):
l+=1
else:
r-=1
return [-1,-1]
88. 合并两个有序数组
给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n 。 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例:
输入: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3
输出:[1,2,2,3,5,6]
题解:
设置3个指针i,j,k,分别用i,j从后往前遍历nums1,nums2,k指针记录需要写入的位置
如果nums1[i]>nums2[j],nums1[k]=nums1[i],i-=1;否则nums1[k]=nums2[j],j-=1;k-=1
def f(a,b,m,n):
i,j,k=m-1,n-1,m+n-1
while(i>=0 and j>=0):
if(a[i]>b[j]):
a[k]=a[i]
i-=1
else:
a[k]=b[j]
j-=1
k-=1
while(j>=0):
a[k]=b[j]
j-=1
k-=1
return a
26. 删除排序数组中的重复项
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。 示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。 // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 for (int i = 0; i < len; i++) { print(nums[i]); }
题解:
设置两个指针i,j;i记录没有重复的数的位置,j向前遍历,直到遍历到数组的最后一个位置。
def f(a):
i,j=0,1
while(j<len(a)):
if(a[j]!=a[i]):
i+=1
a[i]=a[j]
j+=1
return i+1
nums = [0,0,1,1,1,2,2,3,3,4]
r=f(nums)
print(nums[0:r])
514. 自由之路
电子游戏“辐射4”中,任务“通向自由”要求玩家到达名为“Freedom Trail Ring”的金属表盘,并使用表盘拼写特定关键词才能开门。
给定一个字符串 ring,表示刻在外环上的编码;给定另一个字符串 key,表示需要拼写的关键词。您需要算出能够拼写关键词中所有字符的最少步数。
最初,ring 的第一个字符与12:00方向对齐。您需要顺时针或逆时针旋转 ring 以使 key 的一个字符在 12:00 方向对齐,然后按下中心按钮,以此逐个拼写完 key 中的所有字符。
旋转 ring 拼出 key 字符 key[i] 的阶段中:
- 您可以将 ring 顺时针或逆时针旋转一个位置,计为1步。旋转的最终目的是将字符串 ring 的一个字符与 12:00 方向对齐,并且这个字符必须等于字符 key[i] 。
- 如果字符 key[i] 已经对齐到12:00方向,您需要按下中心按钮进行拼写,这也将算作 1 步。按完之后,您可以开始拼写 key 的下一个字符(下一阶段), 直至完成所有拼写。
示例:
输入: ring = "godding", key = "gd" 输出: 4 解释: 对于 key 的第一个字符 'g',已经在正确的位置, 我们只需要1步来拼写这个字符。 对于 key 的第二个字符 'd',我们需要逆时针旋转 ring "godding" 2步使它变成 "ddinggo"。 当然, 我们还需要1步进行拼写。 因此最终的输出是 4。
提示:
- ring 和 key 的字符串长度取值范围均为 1 至 100;
- 两个字符串中都只有小写字符,并且均可能存在重复字符;
- 字符串 key 一定可以由字符串 ring 旋转拼出。
题解:设置两指针,指针i循环遍历ring,指针j遍历key
32. 最长有效括号
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()" 输出: 2
解释: 最长有效括号子串为"()"
示例 2: 输入: ")()())" 输出: 4
解释: 最长有效括号子串为"()()"
题解:
设定一个栈q遍历字符串,设定一个max_len记录最大匹配数据,如果是')',出栈,如果栈为空,下标进栈,如果不为空,max_len=max(max_len,i-q.top());
否则下标继续进栈
def f(s):
q=[-1]
max_len=0
k=0
while(k<len(s)):
if(s[k]==')'):
q.pop()
if(q):
max_len=max(max_len,k-q[-1])
else:
q.append(k)
else:
q.append(k)
k+=1
return max_len