二分查找和双指针放一起写了。二分查找自己是双指针的特殊情况。
注:有序数组,优先考虑二分
二分
34(二分):找不到的话,输出为[-1,-1],找得到,取两个指针在index往左往右分别走,到第一个不相同的数为止。注意下标不能越界~
python版本:
i,j = 0,len(nums) - 1
while i<=j:
mid = (i+j) //2
if(nums[mid] == mid):
i = mid + 1
else:
j = mid - 1
return i
278:每次mid,满足isBadVersion(mid) = false且isBadVersion(mid) = true
35:二分,left < right,插入位置为right。
如果mid < 右侧: 右侧有序,r = mid
如果mid = 右侧: 有重复,r--
如果mid > 右侧: l = mid + 1
双指针
977:左指针在0,右指针在right,每次找最大的。
189:
第一次:原地reverse数组
第二次:reverse前k个
第三次:reverse后n-k个
283:一个指针记录非零的index;一个指针记录总长中现在所在位置,每遇到一个非零的就与前面的index互换位置,index++
167:指针一在最左侧,指针二在最右侧,大于target,则指针二--;小于target,则指针一++
15:这个双指针非常有意思,可以把O(n3)的算法降低到O(n2)。先对数组进行排序,然后从左往右开始,i、j、k代表下标 i < j < k
index从i + 1 ~ size - 1 的范围内找两数之和为 -nums[i]的数值。
11:
11题个人认为最难的地方在于想到用双指针解这个问题。一旦想到用双指针,每次移动较小一侧数值的指针,可以很容易解决。算法从O(n2)降低到O(n)。
滑动窗口也算是双指针的直接用处。个人认为这并不分家。
一个数组array[26]存放从a~z的所有字母出现频率。左右指针规定一个窗口,窗口内记录对所有字符出现频率,窗口的频率存储在数组brray[26]里。比较array和brray是否相同。每向右滑动一次,滑出的brray[j-psize]--,brray[j]++
16
ijk三层循环找最小值会超时,因为重复了很多内容:相同数字的内容、而且jk两个层是可以用一个双指针循环。
1、先sort一下整个数组,保证nums数组有序;使用变量abs_count计算整个数组的count;
2、
for i in nums:
if num[i-1] == nums[i] continue
j ,k := i+1,size - 1
while(j<k)
value := nums[i]+nums[j]+nums[k]
if value = target
return value
else if value < target
abs_count ,result := min(abs_count,abs(value - target)),value
while(j + 1< size && nums[j] = nums[j+1]) j++
j++
else
abs_count ,result := min(abs_count,abs(value - target)),value
while (k>0 && nums[k] == nums[k - 1]) k--
k--
return result