代码随想录算法训练营第二天 |977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

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://programmercarl.com/0209.%E9%95%BF%E5%BA%A6%E6%9C%80%E5%B0%8F%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84.html

视频讲解: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
}

总结

二分法

这玩意真的是 一看就会一写就废啊,容易处理不好边界问题,一般自己写的时候都是左闭右闭的写法,这次写的时候写了左开右闭的写法,左开右闭真的很妙

双指针

双指针,有很多思路 快慢指针,滑动窗口。

比如

  • 移除元素是 快慢指针,一开始写的时候还想着调换啥的,结果了解到更简单的快慢指针,快指针去快速遍历确认条件,然后慢指针记录,返回的时候直接返回慢指针的角标就能解决
  • 还有这个有序数组的平方,双指针,俩指针向中间走,也很妙
  • 长度最小的子数组就是滑动窗口,滑动窗口要记得及时维护窗口的大小

滑动窗口

我觉得滑动窗口也是双指针的一类吧

主要注意窗口什么时候收缩什么时候更新

数组总结

明显第三刷手感是有那么一点了 虽然还是需要看一下思路,但是明显会写了,什么叫笨鸟先飞 三刷巩固 实在不行就四刷 算法么 刷就完事

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值