704.二分查找
题目描述:给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。
解题思路
因为是有序数组,二分查找的最关键的问题就在于边界的区分,这里选择左闭右闭区间**[left,right]来解决问题。这时right=nums.Length-1**,而while中的条件就是left<=right。
遇到的问题及解决方案
在while循环中,对于mid的改变不够清晰。
当 target < nums[mid] 时(即 target 在左区间时),对应的搜索区间为 [left, mid - 1],因为 mid 已经搜索过了,所以我们只需在 mid 左侧的闭区间内进行搜索;
当== target > nums[mid] 时(即 target 在右区间时),对应的搜索区间为 [mid + 1, right],解释同上;
当 target = nums[mid] ==时直接返回mid即可。
当循环结束时,left == right + 1,未找到目标,返回 -1。
27.移除元素
由于题目要求原地修改,则我们不能重新 new 一个新的数组,而是只能在原数组上进行操作,最后返回一个长度。
解题思路
1.暴力解法用两个for循环一个用来遍历数组元素,一个用来更新数组。
2.双指针中快指针可以理解成在旧数组中找非目标元素,然后赋值给慢指针指向的新数组,虽然都指向一个数组。
遇到的问题及解决方案
1.在暴力解法更新完数组元素后没有更新i和nums.Length的长度,因为下标i以后的数值都向前移动了一位,所以i也向前移动一位,这是因为循环一次i要自增。
2.没有搞清楚两个指针的含义,思路转换为代码时不会写,应该寻找非目标元素赋值给慢指针并且将慢指针更新。在返回时返回的是slow,slow刚好是新数组的大小。
总结
这两题之间有点类似的,他们都是在不断缩小 left 和 right 之间的距离,每次需要判断的都是 left 和 right 之间的数是否满足特定条件。对于「移除元素」这个写法本质上还可以理解为,我们拿 right 的元素也就是右边的元素,去填补 left 元素也就是左边的元素的坑,坑就是 left 从左到右遍历过程中遇到的需要删除的数,因为题目最后说超过数组长度的右边的数可以不用理,所以其实我们的视角是以 left 为主,这样想可能更直观一点。用填补的思想的话可能会修改元素相对位置,这个也是题目所允许的。