网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
第8次报价:1951 高了
第9次报价:1756 高了
第10次报价:1658 低了
第11次报价:1707 高了
第12次报价:1682 高了
第13次报价:1670 正确!
这个次数不高于log2(100000) ≈ 16.61,所以二分查找的时间复杂度为 O(log n)。
力扣实战
查找元素的首末位置
Find-first-and-last-position-of-element-in-sorted-array
给定一个按照升序排列的整数数组 nums
,和一个目标值 target
。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target
,返回 [-1, -1]
。
进阶:
- 你可以设计并实现时间复杂度为
O(log n)
的算法解决此问题吗?
示例 1:
**输入:**nums = [5,7,7,8,8,10], target = 8
**输出:**[3,4]
示例 2:
**输入:**nums = [5,7,7,8,8,10], target = 6
**输出:**[-1,-1]
示例 3:
**输入:**nums = [], target = 0
**输出:**[-1,-1]
提示:
0 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
nums
是一个非递减数组-10^9 <= target <= 10^9
代码:
package main
import "fmt"
func searchRange(nums []int, target int) []int {
left, right := -1, -1
// 查找左边界
l, r := 0, len(nums)-1
for l <= r {
mid := (l + r) / 2
if nums[mid] == target {
left = mid
r = mid - 1
} else if nums[mid] > target {
r = mid - 1
} else {
l = mid + 1
}
}
// 如果左边界没找到,直接返回
if left == -1 {
return []int{-1, -1}
}
// 查找右边界
l, r = 0, len(nums)-1
for l <= r {
mid := (l + r) / 2
if nums[mid] == target {
right = mid
l = mid + 1
} else if nums[mid] > target {
r = mid - 1
} else {
l = mid + 1
}
}
return []int{left, right}
}
func main() {
nums := []int{5, 7, 7, 8, 8, 10}
fmt.Println(searchRange(nums, 8))
fmt.Println(searchRange(nums, 6))
nums = []int{}
fmt.Println(searchRange(nums, 0))
}
x 的平方根 Sqrt x
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分,小数部分将被 舍去 。
**注意:**不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
示例 1:
**输入:**x = 4
**输出:**2
示例 2:
**输入:**x = 8
**输出:**2
**解释:**8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
提示:
0 <= x <= 2^31 - 1
代码:
package main
import (
"fmt"
)
func mySqrt(x int) int {
left, right := 0, x
res := -1
for left <= right {
mid := left + (right-left)/2
guess := mid * mid
if guess <= x {
res = mid
left = mid + 1
} else {
right = mid - 1
}
}
return res
}
func main() {
fmt.Println(mySqrt(4))
fmt.Println(mySqrt(8))
fmt.Println(mySqrt(122))
}
寻找旋转排序数组中的最小值
Find-minimum-in-rotated-sorted-array
已知一个长度为 n
的数组,预先按照升序排列,经由 1
到 n
次 旋转 后,得到输入数组。例如,原数组 nums = [0,1,2,4,5,6,7]
在变化后可能得到:
- 若旋转
4
次,则可以得到[4,5,6,7,0,1,2]
- 若旋转
7
次,则可以得到[0,1,2,4,5,6,7]
注意,数组 [a[0], a[1], a[2], ..., a[n-1]]
旋转一次 的结果为数组 [a[n-1], a[0], a[1], a[2], ..., a[n-2]]
。
给你一个元素值 互不相同 的数组 nums
,它原来是一个升序排列的数组,并按上述情形进行了多次旋转。请你找出并返回数组中的 最小元素 。
你必须设计一个时间复杂度为 O(log n)
的算法解决此问题。
示例 1:
**输入:**nums = [3,4,5,1,2]
**输出:**1
**解释:**原数组为 [1,2,3,4,5] ,旋转 3 次得到输入数组。
示例 2:
**输入:**nums = [4,5,6,7,0,1,2]
**输出:**0
**解释:**原数组为 [0,1,2,4,5,6,7] ,旋转 4 次得到输入数组。
示例 3:
**输入:**nums = [11,13,15,17]
**输出:**11
**解释:**原数组为 [11,13,15,17] ,旋转 4 次得到输入数组。
提示:
n == nums.length
1 <= n <= 5000
-5000 <= nums[i] <= 5000
nums
中的所有整数 互不相同nums
原来是一个升序排序的数组,并进行了1
至n
次旋转
代码:
package main
import "fmt"
func findMin(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
mid := left + (right-left)/2
if nums[mid] > nums[right] {
left = mid + 1
} else {
right = mid
}
}
return nums[left]
}
func main() {
nums := []int{3, 4, 5, 1, 2}
fmt.Println(findMin(nums))
nums = []int{4, 5, 6, 7, 0, 1, 2}
fmt.Println(findMin(nums))
nums = []int{11, 13, 15, 17}
fmt.Println(findMin(nums))
}
寻找峰值
Find Peak Element
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums
,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞
。
你必须实现时间复杂度为 O(log n)
的算法来解决此问题。
示例 1:
**输入:**nums = [1,2,3,1]
**输出:**2
**解释:**3 是峰值元素,你的函数应该返回其索引 2。
示例 2:
**输入:**nums = [1,2,1,3,5,6,4]
**输出:**1 或 5
**解释:**你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
提示:
1 <= nums.length <= 1000
-2^31 <= nums[i] <= 2^31 - 1
- 对于所有有效的
i
都有nums[i] != nums[i + 1]
代码:
package main
import "fmt"
func findPeakElement(nums []int) int {
left, right := 0, len(nums)-1
for left < right {
mid := left + (right-left)/2
if nums[mid] > nums[mid+1] {
right = mid
} else {
left = mid + 1
}
}
return left
}
func main() {
nums := []int{1, 2, 3, 1}
fmt.Println(findPeakElement(nums))
nums = []int{1, 2, 1, 3, 5, 6, 4}
fmt.Println(findPeakElement(nums))
}
有效的完全平方数
Valid Perfect Square
给定一个 正整数 num
,编写一个函数,如果 num
是一个完全平方数,则返回 true
,否则返回 false
。
进阶:不要 使用任何内置的库函数,如 sqrt
。
示例 1:
**输入:**num = 16
**输出:**true
示例 2:
**输入:**num = 14
**输出:**false
提示:
1 <= num <= 2^31 - 1
代码:
package main
import "fmt"
func isPerfectSquare(num int) bool {
left, right := 1, num
for left <= right {
mid := left + (right - left) / 2
square := mid * mid
if square == num {
return true
} else if square < num {
left = mid + 1
} else {
right = mid - 1
}
}
return false
}
func main() {
fmt.Println(isPerfectSquare(16))
fmt.Println(isPerfectSquare(14))
}
分割数组的最大值
Split-array-largest-sum
给定一个非负整数数组 nums
和一个整数 m
,你需要将这个数组分成 m
个非空的连续子数组。
设计一个算法使得这 m
个子数组各自和的最大值最小。
示例 1:
**输入:**nums = [7,2,5,10,8], m = 2
**输出:**18
**解释:**
一共有四种方法将 nums 分割为 2 个子数组。
其中最好的方式是将其分为 [7,2,5] 和 [10,8] 。
因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。
示例 2:
**输入:**nums = [1,2,3,4,5], m = 2
**输出:**9
示例 3:
**输入:**nums = [1,4,4], m = 3
**输出:**4
提示:
1 <= nums.length <= 1000
0 <= nums[i] <= 10^6
1 <= m <= min(50, nums.length)
package main
import "fmt"
func splitArray(nums []int, m int) int {
left, right := 0, 0
for _, num := range nums {
right += num
if left < num {
left = num
}
}
for left <= right {
mid := left + (right-left)/2
if check(nums, m, mid) {
right = mid - 1
} else {
left = mid + 1
}
}
return left
}
func check(nums []int, m, target int) bool {
sum, cnt := 0, 1
for _, num := range nums {
if sum+num <= target {
sum += num
} else {
sum = num
cnt++
if cnt > m {
return false
}
}
}
return true
}
func main() {
nums := []int{7, 2, 5, 10, 8}
fmt.Println(splitArray(nums, 2))
nums = []int{1, 2, 3, 4, 5}
fmt.Println(splitArray(nums, 2))
nums = []int{1, 4, 4}
fmt.Println(splitArray(nums, 3))
}
第 k 个缺失的正整数
kth-missing-positive-number
给你一个 严格升序排列 的正整数数组 arr
和一个整数 k
。
请你找到这个数组里第 k
个缺失的正整数。
示例 1:
**输入:**arr = [2,3,4,7,11], k = 5
**输出:**9
**解释:**缺失的正整数包括 [1,5,6,8,9,10,12,13,...] 。第 5 个缺失的正整数为 9 。
示例 2:
**输入:**arr = [1,2,3,4], k = 2
**输出:**6
**解释:**缺失的正整数包括 [5,6,7,...] 。第 2 个缺失的正整数为 6 。
提示:
1 <= arr.length <= 1000
1 <= arr[i] <= 1000
1 <= k <= 1000
- 对于所有
1 <= i < j <= arr.length
的i
和j
满足arr[i] < arr[j]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
第 5 个缺失的正整数为 9 。
**示例 2:**
**输入:**arr = [1,2,3,4], k = 2
**输出:**6
**解释:**缺失的正整数包括 [5,6,7,…] 。第 2 个缺失的正整数为 6 。
**提示:**
* `1 <= arr.length <= 1000`
* `1 <= arr[i] <= 1000`
* `1 <= k <= 1000`
* 对于所有 `1 <= i < j <= arr.length` 的 `i` 和 `j` 满足 `arr[i] < arr[j]`
[外链图片转存中...(img-SupoEgTx-1715721125404)]
[外链图片转存中...(img-CyOSso1m-1715721125405)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**