代码训练营day02|第一章 数组part02 | 977.有序数组的平方 | 209.长度最小的子数组 | 59.螺旋矩阵II

977.有序数组的平方

题目链接: 有序数组的平方

题目内容:给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。

示例 1:输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]

这是我在看解析之前的解法,这应该就是冒泡算法了吧,比较暴力我感觉,思路就是两个指针,快指针不停的往后跑,一但发现有比慢指针小的数,就和慢指针进行交换,快指针跑完一轮,慢指针就往下进一位。

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i = 0;i < nums.length;i++){
            nums[i] = (int)Math.pow(nums[i],2);
        }
        for(int i = 0;i < nums.length;i++){
            for(int j = i;j < nums.length;j++){
                if(nums[i] > nums[j]){
                    int k = nums[i];
                    nums[i] = nums[j];
                    nums[j] = k;
                }
            }
        }
        return nums;
    }
}

这个解析很有意思,题目我没看清楚,其实这个题有一个不一样的地方就是,它在平方前本来就是一个有序的数组,只不过里面有负数。但含有负数的数列有一个巧妙的地方就在于绝对值最大的数都是在两边,所以说选取两个指针在两端然后向内走进行交换就行。

class Solution {
    public int[] sortedSquares(int[] nums) {
        for(int i = 0; i < nums.length;i++){
            nums[i] = (int)Math.pow(nums[i],2);
        }
        int right = nums.length - 1;
        int left = 0;
        int[] sorted = new int[nums.length];
        int key = right;
        while(key >= 0){
            if(nums[left] <= nums[right]){
                sorted[key] = nums[right];
                right--;
            }
            else{
                sorted[key] = nums[left];
                left++;
            }
            key--;
        }
        return sorted;
    }
}

这是看了一半视频解析后想到的代码,有点占内存,因为为了能从小到大排列我新建了一个数组。

把视频看完了,哈哈哈哈哈发现和我的想法是一样的。

09.长度最小的子数组

题目链接:长度最小的子数组

题目内容:给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

这个题我用暴力写的代码可能太暴力了,后面运行不出来。所以直接学习新方法好了。

主要的方法是滑动窗口思想

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //用滑动窗口的思想来写
        //好像还是太暴力了
        int length = nums.length + 1;
        for(int j = 0;j < nums.length;j++){
            int sum = 0;
            for(int i = 0; i <= j; i++){
                sum += nums[i];
            }
            if(sum < target) continue;
            for(int i = 0; sum >= target;i++){
                //比较length长短
                int s1 = j - i + 1;
                length = s1 < length ? s1 : length;
                sum -= nums[i];
            }
        }
        if(length == nums.length + 1)return 0;
        else return length;
    }
}

这是我最开始理解的双执政思路,但这个方法还是太暴力了,最后的大测试用例还是过不了。。。。。。

看完了视频也理解了,这是优化的解决方案,很快,有一个要点记住就是这个慢指针是不走回头路的,为什么这个办法节约时间就是因为不用走回头路,两头的指针都只需要往前跑就行,就像一个滑动的窗口一样。

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //用滑动窗口的思想来写
        int length = nums.length + 1;
        int sum = 0;
        for(int i = 0,j = 0;j < nums.length;j++){
            sum += nums[j];
            while(sum >= target){
                //比较length长短
                int s1 = j - i + 1;
                length = s1 <= length ? s1 : length;
                sum -= nums[i];
                i++;      
            }
        }
        if(length == nums.length + 1)return 0;
        return length;
    }
}

59.螺旋矩阵II

题目链接:螺旋矩阵

题目内容:

给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。

示例 1:
输入:n = 3
输出:[[1,2,3],[8,9,4],[7,6,5]

直接暴力解答出来了,其实没啥算法上的难点,难就难在边界条件上的考量上,看了一半视频解析也是这么解答的,所以没啥问题。很多地方都要考量清楚,比如一个矩阵有几圈,每一圈比上一圈少几位,短多少这种,考虑清楚就很容易了。还要记得区分奇数和偶数在最后一点里是不一样的,总之就是很多细节。

class Solution {
    public int[][] generateMatrix(int n) {
        int[][] matrix = new int[n][n];
        //一个矩阵有n/2圈
        int num = 1;
        for(int i = 0;i < n/2; i++){
            //上面一段
            for(int j = 0; j < n - 1 - 2*i; j++){
                matrix[i][j + i] = num;
                num++;
            }
            //右侧
            for(int j = 0;j < n - 1 - 2*i; j++){
                matrix[j + i][n-1-i] = num;
                num++;
            }
            //下侧
            for(int j = 0;j < n - 1 - 2*i; j++){
                matrix[n-1-i][n-1-i -j] = num;
                num++;
            }
            //左侧
            for(int j = 0;j < n - 1 - 2*i; j++){
                matrix[n-1-i-j][i] = num;
                num++;
            }
        }
        if(n % 2 == 1 ){
                matrix[n/2][n/2] = num;
                return matrix;
            }
        return matrix;
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值