一、二分查找
题干:给定一个 n
个元素有序的(升序)整型数组 nums
和一个目标值 target
,写一个函数搜索 nums
中的 target
,如果目标值存在返回下标,否则返回 -1
。
一看就会一写就废——核心抓住区间一致性,前闭后开
func search(nums []int, target int) int {
l := 0
r := len(nums)
for l < r {
mid := l + (r-l)>>1
if nums[mid] == target {
return mid
} else if nums[mid] < target {
l = mid + 1
} else {
r = mid
}
}
return -1
}
二、移除元素
题干:给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1)
额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
原地址:. - 力扣(LeetCode)
简单双指针,直接在原数组上覆盖就可以了。
func removeElement(nums []int, val int) int {
i, j := 0, 0
for j < len(nums) {
if nums[j] != val {
nums[i] = nums[j]
i++
}
j++
}
return i
}
三、有序数组的平方
题干: 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
原地址:. - 力扣(LeetCode)
简单双指针即可搞定,相当于两个数组,一个从大到小,一个从小到大,从两边向中间遍历即可。
func sortedSquares(nums []int) []int {
res,p1, p2 := len(nums)-1,0, len(nums)-1
ans := make([]int, len(nums))
for p1 <= p2 {
l := nums[p1] * nums[p1]
r := nums[p2] * nums[p2]
if l >= r {
ans[res] = l
res--
p1++
} else {
ans[res] = r
res--
p2--
}
}
return ans
}
四、长度最小的子数组
题干:给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
原地址:. - 力扣(LeetCode)
暴力解法为循环遍历,外循环指向单个元素,内循环判断该元素往后加上多少个元素会超过s,并记录此时长度。(跑不过leetcode最后的几个测试案例)
双指针解法也可以称为滑动窗口,首先从第一个元素开始算最小长度,当达到阈值后减去第一个元素,若此时仍大于,则继续减去第二个元素。直到小于s后,继续向后遍历。下面是滑动窗口法。这里length := len(nums) + 1是保证当在数组所有数加起来达不到s的情况下能够返回0。
func minSubArrayLen(target int, nums []int) int {
slow, fast, sum := 0, 0, 0
length := len(nums) + 1
for fast < len(nums) {
sum += nums[fast]
for sum >= target {
long := fast - slow + 1
if long < length {
length = long
}
sum = sum - nums[slow]
slow++
}
fast++
}
if length == len(nums)+1 {
length = 0
}
return length
}
五、螺旋矩阵II
题干:给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。
原地址:. - 力扣(LeetCode)
和第一题一样要注意区间一致性的问题。怎么样让每轮螺旋遍历时不会进行重复赋值是本题的关键。
正方形边长为4n-4。那么就是每轮只遍历一个n-1个元素即可,自然选择从0到n-2这n-1个元素,这里用offset来控制不要去对最后一个元素来赋值。
这里的control其实是比较好想的,因为你是要螺旋把一个正方形给填满嘛,只看行不看列,那你一次也就填两列,所以对于一个正方形,你要填的次数就是边长n/2次。如果是奇数的边长那最后一次是一个边长为1的小正方形。
startx和starty是用来定义每轮遍历的起点和终点的,假如一个边长为6的正方形,那么遍历一次后就成了一个边长为4的正方形,如何实现这一过程呢,就同这两个变量进行控制就可以了。
func generateMatrix(n int) [][]int {
ans := make([][]int, n)
for i := 0; i < n; i++ {
ans[i] = make([]int, n)
}
startx, starty, i, j, offset, temp := 0, 0, 0, 0, 1, 1
control := n / 2
for control != 0 {
j = startx
i = startx
for ; j < n-offset; j++ {
ans[starty][j] = temp
temp++
}
for ; i < n-offset; i++ {
ans[i][j] = temp
temp++
}
for ; j > startx; j-- {
ans[i][j] = temp
temp++
}
for ; i > startx; i-- {
ans[i][j] = temp
temp++
}
starty++
startx++
offset++
control--
}
if n%2 == 1 {
ans[n/2][n/2] = temp
}
return ans
}