刷题第二天| 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

977.Squares of a Sorted Array

题目链接:977. Squares of a Sorted Array
思路链接:代码随想录数组-有序数组的平方

思路

暴力解法 O(n + nlogn):平方之后,直接调用quick sort
双指针法 O(n):定义一个新的空数组。在数组左端定义一个left指针,在右端定义一个right指针,比较left与right指向的值的大小。值较大者写入数组的末端,更新值较大的指针,直到left > right

心路历程

刚开始拿到题, 就想到暴力解法;然后也想到了双指针法,但是指针的处理还是有点问题,导致没有用双指针法做出来,说明对双指针法理解还是不够。

Code

class Solution {
    public int[] sortedSquares(int[] nums) {
        // 暴力解法
        for (int i = 0; i < nums.length; i++) {
            nums[i] = nums[i] * nums[i];
        }
        
        Arrays.sort(nums);
        return nums;
    }
}
class Solution {
    public int[] sortedSquares(int[] nums) {
        // 双指针法
        int[] ans = new int[nums.length];
        int k = nums.length - 1;
        for (int high = nums.length - 1, low = 0; low <= high;) {
            if ((nums[high] * nums[high]) > (nums[low] * nums[low])) {
                ans[k] = nums[high] * nums[high];
                high--;
                k--;
            } else {
                ans[k] = nums[low] * nums[low];
                low++;
                k--;
            }
        }
        return ans;
    }
}

209. Minimum Size Subarray Sum

题目链接:209.Minimum Size Subarray Sum
思路链接:代码随想录数组-长度最小的子数组

思路

暴力解法 O(n^2):用两个循环,遍历找出所有符合条件的subarray
滑动窗口法:类似于双指针法,使用一个for循环完成暴力解法两个for循环的任务。先定义滑动窗口的起始指针,在for循环条件中定义滑动窗口的终止指针(非常重要!否则与暴力解法没有差别)。在for循环中使用while循环(必须要用while,因为如果用if,只会更新一次),只要sum >= target, 起始指针+1,更新sum,减去起始指针原来指向的值。注意不存在符合条件的子数组的情况!

心路历程

刚开始做题时没看清题目,导致浪费了很多时间。后来写出了暴力解法,但是之前没接触过滑动窗口(也可能忘了),就去看视频了。看完视频文章后,自己动手写了一遍,不难。

Code

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
    	//暴力解法
        int result = Integer.MAX_VALUE;
        for (int i = 0; i < nums.length; i++) {
            int sum = 0;
            int len = 0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                len++;
                if (sum >= target) {
                    if (len < result) {
                        result = len;
                    }
                }
            }
        }
        if (result == Integer.MAX_VALUE) {
            result = 0;
        }
        return result;
    }
}
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // 滑动窗口法
        int low = 0; // 定义起始指针
        int result = Integer.MAX_VALUE; // 初始化return值
        int sum = 0;
        for (int high = 0; high < nums.length; high++) { //定义终止指针
            sum += nums[high];
            while (sum >= target) { // 注意这里使用while,而不是if
                int len = high - low + 1;
                result = len < result ? len : result; // 更新return值
                sum -= nums[low]; // 缩小window
                low++;
                // System.out.println(len);
            }
        }
        // Remember to cope with the exception
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

59. Spiral Matrix II

题目链接:59. Spiral Matrix II
思路链接:代码随想录数组-螺旋矩阵II

思路

只能用暴力解法,不过要注意如何处理边界问题(循环不变量)。按照左闭右开的原则绕圈,先绕上,再绕右,再绕下,再绕左。

心路历程

刚开始做题时有点懵逼,然后偷偷瞟了几眼代码随想录的思路,就自己花时间写了一下。先用递归写了解法,但是调试的过程花了很多时间,不过最后还是成功了。然后看视频文章,再自己实现了迭代写法,不难。还是发现自己的代码实现能力比较弱,要花很多时间,而且写出来的代码不整洁。

Code

class Solution {
	// 递归写法
    private void generateMatrixHelper(int n, int startI, int startJ, int[][] matrix, int k) {
        if (n == 1) {
            matrix[startI][startJ] = k * k;
        } else if (n == 0) {
            return;
        } else {
            int num = 1;
            if (startJ - 1 >= 0) {
                num = matrix[startI][startJ - 1] + 1;
            }
            //画上面
            for (int i = startI, j = startJ; j < startJ + n - 1; j++) {
                matrix[i][j] = num;
                num++;
            }
            //画右边
            for (int i = startI, j = startJ + n - 1; i < startI + n - 1; i++) {
                matrix[i][j] = num;
                num++;
            }
            //画下面
            for (int i = startI + n - 1, j = startJ + n - 1; j > startJ; j--) {
                matrix[i][j] = num;
                num++;
            }
            //画左边
            for (int i = startI + n - 1, j = startJ; i > startI; i--) {
                matrix[i][j] = num;
                num++;
            }
            generateMatrixHelper(n - 2, startI + 1, startJ + 1, matrix, k);
        }
        
    }
     
    public int[][] generateMatrix(int n) {
        int[][] matrix = new int[n][n];
        generateMatrixHelper(n, 0, 0, matrix, n);
        return matrix;
    }
    
}
class Solution {
    public int[][] generateMatrix(int n) {
        // 迭代写法
        int[][] matrix = new int[n][n];
        int count = 1;
        int loop = n / 2;
        int startX = 0;
        int startY = 0;
        int offset = 1;
        while (loop > 0) {
            // 画上面
            int i = startX;
            int j = startY;
            for (; j < n - offset; j++) {
                matrix[i][j] = count;
                count++;
            }
            // 画右边
            for (; i < n - offset; i++) {
                matrix[i][j] = count;
                count++;
            }
            // 画下面
            for (; j > startY; j--) {
                matrix[i][j] = count;
                count++;
            }
            //画左边
            for (; i > startX; i--) {
                matrix[i][j] = count;
                count++;
            }
            startX++;
            startY++;
            loop--;
            offset++;
        }
        
        if (n % 2 == 1) {
            matrix[startX][startY] = n * n;
        }
        return matrix;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值