今日任务
- 977 有序数组的平方 (题目: . - 力扣(LeetCode))
- 209 长度最小的子数组 (题目: . - 力扣(LeetCode))
- 59 螺旋矩阵 II (题目:. - 力扣(LeetCode))
有序数组的平方 (双指针)
给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
想法:
这个题目猛一看其实挺简单的,直接计算所有平方,因为有负整数,还需要再排下序.就可以了,但是要求了有 o(n)的要求,肯定是让整点花活的.
问题:
想到要用到双指针,写代码时采用了快慢双指针,但是没想好处理下一步,如何使数据平方后保存,当时一直纠结在原数组上去处理,想着快慢指针将负数取反和大于 0 的数对比替换(因为是非递减嘛,即数字是递增或相等的),一直卡在这了. 后面看了讲解,才想起我不必在原数组上去操作的(🥲🥲)
解决思路:
创建一个和原数组等长的新数组、使用首尾双指针,计算对比平方之后的值得大小、将大的值插入新数组的尾部(因为非递减的属性,即使左侧是负数,平方之后也可能会是最大的值)、移动指针、循环....
func sortedSquares(nums []int) []int {
result := make([]int,len(nums))
left,right,k := 0,len(nums)-1,len(nums)-1
// for k >= 0{ // 这两个循环条件都可以
for left <= right{
if nums[left]*nums[left] >= nums[right]*nums[right] {
result[k] = nums[left] * nums[left]
left ++
} else {
result[k] = nums[right]*nums[right]
right --
}
k --
}
return result
}
长度最小的子数组 (双指针 窗口滑动)
找出该数组中满足其总和大于等于 target
的长度最小的 连续子数组[numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
想法:
.....看到题没想法,暴力的写法(双重 for 循环)都未写,直接看了题解
问题:
滑动窗口 即快慢双指针,好像不难理解,但是呢对于快慢指针该如何移动要想透彻,还有就是如何统计窗口的大小(小数组的值)
解决思路:
创建一个快慢指针,快指针往前走,同时计算身后元素的累加结果(第一个 for 循环),直到累加结果大于等于目标值了,就先停下来,等一等我们的慢指针(for 循环),这时计算 slow 和 fast 之间的距离,以及就累加结果减去 slow 对应的元素,看看当前窗口的值是否能够大于目标值....
func minSubArrayLen(target int, nums []int) int {
slow, fast := 0, 0
// 搞一个大于数组的值,这个用来存放我们发现的符合条件的数量
result := len(nums)+1
var res []int
sum := 0
for ; fast < len(nums); fast++ {
// 就是先移动快指针
sum += nums[fast]
// 如果 fast 移动到某一步骤,后面的元素大于等于目标值了,则开始移动慢指针,
// 确认一下最少几个元素可满足
for sum >= target {
l := fast - slow + 1
// 保存最小的子数组长度
if l < result {
result = l
res = nums[slow : fast+1]
}
sum -= nums[slow]
slow++
}
}
// 要判断一下这个值,没有符合条件的子数组时,要返回 0
if result > len(nums){
return 0
}
fmt.Println(res)
return result
}
螺旋矩阵 II (有点抽象)
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
想法:
看到题目时,完全没思路,想不出如何去给一个二维数组这样子赋值.......
问题:
起初看了几个题解,其中讲的比较多的什么确定 4 条边的边界,l、r、b、t ,但是看的云里雾里,,,
解决思路:
首先要理解 4 条边界是什么意思....待我总结一下
图片来自题解:. - 力扣(LeetCode)
func generateMatrix(n int) [][]int {
sum := n * n
result := make([][]int, n)
for i := 0; i < n; i++ {
result[i] = make([]int, n)
}
k := 1
l := 0
r := n - 1
t := 0
b := n - 1
// 每个边界 这里遵循的是左闭右闭
for k <= sum {
for i := l; i <= r; i++ {
// 行固定,修改列
result[t][i] = k
k++
}
t++
for i := t; i <= b; i++ {
// 列固定,修改行
result[i][r] = k
k++
}
r--
for i := r; i >= l; i-- {
// 行固定,修改列,
result[b][i] = k
k++
}
b--
// for i := r; i >= t; i-- { // 这个地方写的有问题,但是也碰巧过了
for i := b;i >= t; i -- {
// 列固定,修改行
result[i][l] = k
k++
}
l++
}
return result
}