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

day02:977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵 II

LeetCode 977.有序数组的平方

题目链接:

有序数组的平方

文章讲解:

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、观察题目,数组是非递减顺序,那么最大和最小的一定在数组的头和尾。所以考虑双指针法,i指向头部,j指向尾部

2、因为返回的是每个数字平方的新数组,且任意数字平方后都是大于等于0的,所以每次只要比较数组头尾的两个数的平方大小。

3、将平方后较大的数填充到新数组的末尾,如果是头部数字的平方比较大,那么i++,反之j–;

4、循环结束条件为 i<=j,之所以包含i=j的情况,是因为要在循环内将数组填充到新数组中,若不包含则会直接退出循环,新数组会少一个数。

public class Solution {
    public int[] SortedSquares(int[] nums) {
        int[] result = new int[nums.Length];
        int k = nums.Length - 1; //在新数组中从后向前赋值
        for(int i = 0, j = nums.Length - 1; i <= j;)//双指针部分,i指向头部,j指向尾部
        {
            //头部数字平方大于尾部数字平方
            if(nums[i] * nums[i] > nums[j] * nums[j])
            {
                result[k] = nums[i] * nums[i];
                k--;
                i++;//头部指针右移
            }
            //头部数字平方大于尾部数字平方,以及i=j的情况
            else
            {
                result[k] = nums[j] * nums[j];
                k--;
                j--;
            }
        }
        return result;
    }
}

LeetCode 209.长度最小的‘’子数组

题目链接:

长度最小的子数组

文章讲解:

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循环,不断寻找符合条件的子序列,时间复杂度 O ( n 2 ) O(n^2) O(n2)

public class Solution {
    public int MinSubArrayLen(int target, int[] nums) {
        int result = int.MaxValue;
        int sum = 0;
        int subLength = 0;
        for(int i = 0; i < nums.Length; i++)
        {
            sum = 0;
            for(int j = i; j < nums.Length; j++)
            {
                sum += nums[j];
                if(sum >= target)
                {
                    subLength = j - i + 1;
                    result = result < subLength ? result : subLength;
                    break;
                }
            }
        }
        return result == int.MaxValue ? 0 : result;
    }
}
滑动窗口:

即不断调节子序列的起始位置和 终止位置,从而的到想要的结果。

需要分以下步骤考虑:

1、窗口内是什么?

在本题中,窗口内部是窗口内所有数字加起来的和满足>=target的长度最小的连续子数组。

2、如何移动窗口的起始位置?

如果当前窗口大于target了,窗口就要向前移动,也就是该缩小了。

3、如何移动窗口的结束位置?

窗口的结束位置就是遍历数组的指针。

public class Solution {
    public int MinSubArrayLen(int target, int[] nums) {
        int result = int.MaxValue;
        int slow = 0, fast = 0;
        int sum = 0;
        while(fast < nums.Length)
        {
            sum += nums[fast];
            while(sum >= target)
            {
                result = System.Math.Min(result, fast - slow + 1);
                sum -= nums[slow];
                slow++;
            }
            fast++;
        }
        return result == int.MaxValue ? 0 : result;

    }
}

时间复杂度为 O ( n ) O(n) O(n) :虽然上述代码中有两个while循环,但主要是看每一个元素被操作的次数,每个元素在滑动窗口后进来一次、出去一次,即每个元素都被操作两次,所以时间复杂度是2*n,也就是 O ( n ) O(n) O(n)

LeetCode 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/

思路和解法:

重点:坚持循环不变量原则,首先模拟顺时针画矩阵的过程

  • 填充上行从左到右
  • 填充右列从上到下
  • 填充下行从右到左
  • 填充左列从下到上
public class Solution {
    public int[][] GenerateMatrix(int n) {
        int[][] result = new int[n][];
        for(int i = 0; i < n; i++)
            result[i] = new int[n];
        int count = 1;
        int start = 0;
        int end = n - 1;
        while(count < n * n)
        {
            for(int i = start; i < end; i ++)   result[start][i] = count++;
            for(int i = start; i < end; i++)    result[i][end] = count++;
            for(int i = end; i > start; i--)    result[end][i] = count++;
            for(int i = end; i > start; i--)    result[i][start] = count++;
            start++;
            end--;
        }
        if(n % 2 == 1)
            result[n/2][n/2] = count;
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值