代码随想录算法训练营第一天| 704. 二分查找, 35.搜索插入位置,34. 在排序数组中查找元素的第一个和最后一个位置,27. 移除元素

很久以前的刷题中道崩殂在了数组...所以这部分大概算个二刷? 

704. 二分查找

力扣

二分法前提条件:有序数组 + 无重复元素

另外看到要求O(logn)查找也很有可能是二分法!

middle是用来记录当前位置的,初始化为(left + right)/2

左闭右闭:(right = s.size()-1) + while(left <= right) + (right = middle -1)/(left = middle + 1)。注意这几个判断条件都是配套的!

代码随想录算法训练营第一天| 704. 二分查找, 35.搜索插入位置,34. 在排序数组中查找元素的第一个和最后一个位置,27. 移除元素_第1张图片

 左闭右开:right = s.size() + while(left < right) + (right = middle) + (left = middle + 1)

 (注意因为左边是闭区间,所以left的调整依旧是left = middle + 1)

 35.搜索插入位置

力扣

左闭右闭:整体和上一题类似。特别注意【没找到】是需要返回的位置:left 或 right + 1 

(因为对于左闭右闭,如果没找到,最后一步一定是left = right = middle, 然后left = middle + 1)

34. 在排序数组中查找元素的第一个和最后一个位置 

力扣

重点在于找到一个target后如何找到起始位和结束位

--> 分别写出leftBoarder和rightBoarder的helper function,然后在主方法中引用

注意:

1. 计算出来的右边界是不包含target的右边界,左边界同理。因此在main function中用时需要 {left+1, right-1}

2. 找left & right boarder时,只有【当前点】(nums[target]) 在该boarder那一边时需要单独写出来调整,其余的两种情况(在boarder另一边 & 该点就是)放在一起进行调整,并update boarder (因为有可能是很多个这样的元素)。换句话说如果是leftBoarder,那只有left = middle + 1需要单独拿出来写。

3. 需要在helper function中记录一下boarder没有被赋值的情况(例如设为-2)。如果没有赋值也return {-1,-1}

4. main function中三种情况讨论。存在的情况需要确认(right - left > 1),因为等于1的情况是该数只有一个的情况,不符合此题题意。

以下是getLeftBoarder的代码。getRightBoarder类似。

代码随想录算法训练营第一天| 704. 二分查找, 35.搜索插入位置,34. 在排序数组中查找元素的第一个和最后一个位置,27. 移除元素_第2张图片

 

27. 移除元素

力扣

快慢双指针

1. 如果是在最开始,不涉及任何“覆盖”时进行 nums[slow] = nums[fast]的操作,由于此时slow和fast一样所以不会有任何改变

2. 若遇到了val,此时fast继续前进而slow不变,相当于slow码住了要替换的位置(和数量,如果有连续几个val,fast就会向前移动几个)

3. 此后如果再次遇到非val,则需要用非val替换(slow标记的)val,也就是nums[slow] = nums[fast]

4. 最后slow记录到被替换完的最后一位,return slow

代码随想录算法训练营第一天| 704. 二分查找, 35.搜索插入位置,34. 在排序数组中查找元素的第一个和最后一个位置,27. 移除元素_第3张图片

你可能感兴趣的:(算法,leetcode,c++,数据结构)