704. 二分查找
解答视频链接:www.bilibili.com/video/BV1fA…
二分查找 重中之重就是找到定义的区间
第一种写法:
我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。
区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:
- while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
- if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
(版本一)左闭右闭区间
func search(nums []int, target int) int {
high := len(nums)-1
low := 0
for low <= high {
mid := low + (high-low)/2
if nums[mid] == target {
return mid
} else if nums[mid] > target {
high = mid-1
} else {
low = mid+1
}
}
return -1
}
第二种写法:
如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。
有如下两点:
- while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
- if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
(版本二)左闭右开区间
func search(nums []int, target int) int {
high := len(nums)
low := 0
for low < high {
mid := low + (high-low)/2
if nums[mid] == target {
return mid
} else if nums[mid] > target {
high = mid
} else {
low = mid+1
}
}
return -1
}
27. 移除元素
解答视频链接:www.bilibili.com/video/BV12A… 采用双指针算法,快慢指针。
在这里,我总结,但凡是碰到说明不要用额外空间的数组题,我感觉我们都可以用这种双指针,通过覆盖,换位等等的形式,改变原有数组。
func removeElement(nums []int, val int) int {
slow := 0
for fast := 0; fast <= len(nums) - 1; fast++{
if nums[fast] != val{
nums[slow] = nums[fast]
slow += 1
}
}
return slow
}