977.有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
题目: 给定一个按 非递减顺序的数组 然后返回平方组成新数组,非递减排序,也就弄个递增排序呗
思路:
1.暴力解法 全给平方了然后再排序一下
2.双指针方法,因为是非递减所以最左和最右的平方可能都是最大的,中间的就是小,然后两边向中间遍历,取到大的就放入到新数组的最右边
//暴力解法 O(n+nlogn)
func sortedSquares(nums []int) []int {
for i := 0; i < len(nums); i++ {//O(n)
nums[i]=nums[i]*nums[i]
}
sort.Ints(nums)//O(nlogn)
return nums
}
//双指针(O(n))
func sortedSquares(nums []int) []int {
i,j,k:=0,len(nums)-1,len(nums)-1
result:=make([]int, len(nums))
for i<=j{
a := nums[i]*nums[i]
b := nums[j]*nums[j]
if a < b{
result[k] = b
j--
}else{
result[k] = a
i++
}
k--
}
return result
}
209.长度最小的子数组
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
视频讲解:https://www.bilibili.com/video/BV1tZ4y1q7XE
题目: 给个数组和一个目标和,求出最小目标和的长度
思路: 滑动窗口,俩指针 一个窗口右边一个窗口左边,大于目标和左边向右收缩,小于目标和右边扩张,这题自己写的时候三个for 特别蠢
后面发现i就直接++就可以不需要套上i的循环
//O(n) 虽然有两次循环但是第二次循环只做一两次操作 所以,时间复杂度o(n)
func minSubArrayLen(target int, nums []int) int {
//维护一个窗口
//记录窗口长度
n := len(nums)
sum,i := 0,0
result := n+1
for j := i; j < n; j++ {
//j向前走
sum+=nums[j]
for sum>=target{
//满足窗口里的数大于目标数然后窗口左侧向右收缩
sum-=nums[i]
result = min(result,j - i + 1)
i++
}
}
if result == n+1{
result =0
}
return result
}
func min(i,j int) int {
if i < j {
return i
}
return j
}
59.螺旋矩阵II
题目链接:https://leetcode.cn/problems/spiral-matrix-ii/
文章讲解:https://programmercarl.com/0059.%E8%9E%BA%E6%97%8B%E7%9F%A9%E9%98%B5II.html
视频讲解:https://www.bilibili.com/video/BV1SL4y1N7mV/
题目:给个n 然后求个n*n的矩阵,顺时针填充0-n^2
思路:还是看清风的思路,都第三遍了!!!还是蠢,但是写着顺手很多理解也很快,既然是个矩阵那么肯定有四个变量up down left right 模拟遍历,这个思路有点左开右闭的思路,写的时候注意是> < ++ --就行了
func generateMatrix(n int) [][]int {
up,down,left,right:=0,n-1,0,n-1
ans:=make([][]int, n)
for i:= range ans {
ans[i]=make([]int, n)
}
cur := 1
for cur<=n*n{
//第一排 向右走
for i := left; i <=right ; i++ {
ans[up][i]= cur
cur++
}
up++
//最右边一排向下走
for i := up; i <= down; i++ {
ans[i][right]=cur
cur++
}
right--
//下排往左走
for i := right; i >= left; i-- {
ans[down][i]=cur
cur++
}
down--
//左下往左上
for i := down; i >= up; i-- {
ans[i][left]=cur
cur++
}
left++
}
return ans
}
总结
二分法
这玩意真的是 一看就会一写就废啊,容易处理不好边界问题,一般自己写的时候都是左闭右闭的写法,这次写的时候写了左开右闭的写法,左开右闭真的很妙
双指针
双指针,有很多思路 快慢指针,滑动窗口。
比如
- 移除元素是 快慢指针,一开始写的时候还想着调换啥的,结果了解到更简单的快慢指针,快指针去快速遍历确认条件,然后慢指针记录,返回的时候直接返回慢指针的角标就能解决
- 还有这个有序数组的平方,双指针,俩指针向中间走,也很妙
- 长度最小的子数组就是滑动窗口,滑动窗口要记得及时维护窗口的大小
滑动窗口
我觉得滑动窗口也是双指针的一类吧
主要注意窗口什么时候收缩什么时候更新
数组总结
明显第三刷手感是有那么一点了 虽然还是需要看一下思路,但是明显会写了,什么叫笨鸟先飞 三刷巩固 实在不行就四刷 算法么 刷就完事