704. 二分查找
代码
func search(nums []int, target int) int {
tmp := 0
var find func(i, j int)int
find = func (i, j int) int {
if i>j {
return -1
}
tmp = (i+j)/2
if nums[tmp]==target {
return tmp
} else if nums[tmp]<target {
return find(tmp+1, j)
} else {
return find(i, tmp-1)
}
}
return find(0, len(nums)-1)
}
思路
- 二分查找,注意边界条件
性能
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
35. 搜索插入位置
代码
func searchInsert(nums []int, target int) int {
tmp := 0
n := len(nums)
var find func(i, j int)int
find = func(i, j int)int {
if i>j {
return i
}
tmp = (i+j)/2
if nums[tmp]==target {
return tmp
} else if nums[tmp]<target {
return find(tmp+1, j)
} else {
return find(i, tmp-1)
}
}
return find(0, n-1)
}
思路
- 二分,需要注意的只有这句话
if i>j {
return i
}
性能
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
34. 在排序数组中查找元素的第一个和最后一个位置
代码
func searchRange(nums []int, target int) []int {
n := len(nums)
tmp := 0
var ans []int
var find func(i, j int)
find = func(i, j int) {
if i>j {
ans = []int{-1, -1}
return
}
tmp = (i+j)/2
if nums[tmp]==target {
i := tmp-1
for tmp>=0 && nums[tmp]==target {
tmp--
}
ans = []int{tmp+1}
tmp = i+1
for tmp<n && nums[tmp]==target {
tmp++
}
ans = append(ans, tmp-1)
} else if nums[tmp]<target {
find(tmp+1, j)
} else {
find(i, tmp-1)
}
}
find(0, n-1)
return ans
}
思路
- 二分找到任何一个相同的值,然后向前找起点,向后找终点。
性能
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
33. 搜索旋转排序数组
代码
func search(nums []int, target int) int {
n := len(nums)
tmp := 0
ans := -1
var find func(i, j int)
find = func(i, j int) {
if i>j {
return
}
tmp = (i+j)/2
if nums[tmp]==target {
ans = tmp
return
} else if target>=nums[i] && target<nums[tmp] {
find(i, tmp-1)
} else if target<=nums[j] && target>nums[tmp] {
find(tmp+1, j)
} else {
find(i, tmp-1)
find(tmp+1, j)
}
}
find(0, n-1)
return ans
}
思路
- 二分法,
- 判断左右是否有序
- 左边有序,且在左边,只二分左边
- 右边有序,且在右边,只二分右边
- 否则都二分
性能
- 时间复杂度:O(logn)
- 空间复杂度:O(1)
74. 搜索二维矩阵
代码
func searchMatrix(matrix [][]int, target int) bool {
n := len(matrix)
if n==0 {
return false
}
m := len(matrix[0])
i, j := 0, -1
tmp := 0
var find1 func(l, r int)
find1 = func(l, r int) {
if l>r {
i=r
return
}
tmp = (l+r)/2
if matrix[tmp][0]==target {
i = tmp
} else if matrix[tmp][0]<target {
find1(tmp+1, r)
} else {
find1(l, tmp-1)
}
}
find1(0, n-1)
if i<0 || i>=n {
return false
}
var find2 func(l, r int)
find2 = func(l, r int) {
if l>r {
return
}
tmp = (l+r)/2
if matrix[i][tmp]==target {
j = tmp
} else if matrix[i][tmp]<target {
find2(tmp+1, r)
} else {
find2(l, tmp-1)
}
}
find2(0, m-1)
if j==-1 {
return false
}
return true
}
思路
两次二分,先找到可能的行,在这行里找到底在哪。
性能
- 时间复杂度:O(logn)
- 空间复杂度:O(1)