day2 | 数组 part-2 | 977 有序数组的平方、209 长度最小的子数组、59 螺旋矩阵 II

今日任务 


有序数组的平方 (双指针)

        给你一个按 非递减顺序 排序的整数数组 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
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值