代码随想录算法训练营第一天打卡记录
题目链接:
704. 二分查找
27. 移除元素
知识点链接:
数组理论基础
二分法
前提条件
数组为有序数组,同时题目还强调数组中无重复元素,因为一旦有重复元素,使用二分查找法返回的元素下标可能不是唯一的。
区间定义
左闭右闭[left, right]
右闭的right是一个高富帅,他已经得到了,所以有资格挥霍一个middle,
right = middle - 1
func search(nums []int, target int) int {
left, right := 0, len(nums) - 1
for left <= right {
middle := (left + right)/2
if nums[middle] > target{
right = middle - 1
}else if nums[middle] < target {
left = middle + 1
}else{
return middle
}
}
return -1
}
左闭右开[left, right)
右开是个舔狗,得不到的拼命想要握在手中
right = middle
func search(nums []int, target int) int {
left, right := 0, len(nums)
for left < right {
middle := (left + right)/2
if nums[middle] > target{
right = middle
}else if nums[middle] < target {
left = middle + 1
}else{
return middle
}
}
return -1
}
left是高冷的女神,全程观战示意挥霍
left = middle + 1
双指针法
双向奔赴才是浪漫
- 自写
func removeElement(nums []int, val int) int {
left, right := 0, len(nums) - 1
// 从左向右依次遍历
for left <= right {
// 找到第一个val,就将其与右边第一个不是val的位置互换
if nums[left] == val {
for left <= right {
if nums[right] == val{
right -= 1
continue
}else {
nums[left], nums[right] = nums[right], nums[left]
break
}
}
}else {
left += 1
}
}
return left
}
- 教程版
读起来更加简洁,感觉上更加自动化,不累赘。
内层的两个for循环必须也得加上left <= right,否则会溢出来。
func removeElement(nums []int, val int) int {
left, right := 0, len(nums) - 1
for left <= right {
for left <= right && nums[left] != val {
left ++
}
for left <= right && nums[right] == val{
right --
}
fmt.Println(left, right)
if left < right{
nums[left] = nums[right]
left ++
right --
}
}
return left
}