第二天,需要重做螺旋矩阵II

文章介绍了三种对排序数组进行平方的方法,包括暴力求解、使用集合和双指针优化。其中双指针法具有较好的时间复杂度。此外,还讨论了使用滑动窗口求解最小子数组和问题,以及一种螺旋矩阵生成算法。文章强调了算法优化和效率的重要性。

Day 2

  1. Squares of a Sorted Array 的三种方法
Pass by brute force:

Sqaure each element, then sort. But runtime complexity is O ( n 2 ) O(n^2) O(n2), space complexity O ( 1 ) O(1) O(1).

Pass by having a Set:

put the squared value in a Set, then put back into the array. Runtime complexity goes down to O ( n ) O(n) O(n), space complexity increases to O ( n ) O(n) O(n).

Use double pointer:
class Solution {
    private int search(int[] nums){
        int left = 0;
        int right = nums.length-1;
        int ans = nums.length;

        while(left <= right){
            int mid = (left + right) >> 1;
            if(nums[mid] >= 0){
                ans = mid;
                right = mid-1;
            }else if(nums[mid] < 0){
                left = mid+1;
            }
        }
        return ans;

    }

    public int[] sortedSquares(int[] nums) {
        int len = nums.length;
        int[] arr = new int[len];

        int r = search(nums); //找第一个大于等于0的数
        int l = r-1;

        if(r == len) r = 0;

        for(int i = 0; i < len; ++i){
            if(r < len && l >= 0 && nums[r]*nums[r] >= nums[l]*nums[l]){ //正常比
                arr[i] = nums[l]*nums[l];
                --l;
            }else if(r < len) {                                         //如果r还没比完
                arr[i] = nums[r]*nums[r];
                ++r;
            }else{                                                      //如果l还没比完
                arr[i] = nums[l]*nums[l];
                --l;
            }
        }

        return arr;
    }
}

这个binary search这部分代码融入了昨天的知识点,算法效率很高。

 class Solution {
    public int[] sortedSquares(int[] nums) {
        int len = nums.length;
        int[] arr = new int[len];

        int r = len-1;
        int l = 0;
        int i = len-1;

        while(l <= r && i >= 0){
            if(nums[l] * nums[l] >= nums[r] * nums[r]){
                arr[i] = nums[l] * nums[l];
                ++l;
            }else{
                arr[i] = nums[r] * nums[r];
                --r;
            }
            --i;
        }

        return arr;
    }
}

这个是答案思路,从两头开始找的,而不是从负数到零的这个分界线。确实是言简意赅。

2.Minimum Size Subarray Sum
这题意外的很好做,不会是我进步了吧(笑)
用滑动窗口,先是向前一直加到target,后面后指针一直跟到小于target即可!

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        int l = 0, r = 0, len = nums.length, sum = 0, max = Integer.MAX_VALUE;
        while(r < len){
            while(r < len && sum < target){
                sum += nums[r];
                ++r;
            }
            if(r-l+1 < max) max = r-l+1;
            while(sum >= target){
                sum -= nums[l];
                ++l;
            }
            if(r-l+1 < max) max = r-l+1;
        }
        int sum2 = 0;
        for(int i : nums) sum2 += i;
        return sum2 < target? 0 : max;
    }
}

答案的解法思路和我一样,但更简洁。思路是:默认加,但如果加多了,就写循环往外吐元素。
time complexity: O ( 2 n ) = O ( n ) O(2n) = O(n) O(2n)=O(n).
答案解法见下文:

class Solution {
public:
    int minSubArrayLen(int s, vector<int>& nums) {
        int result = INT32_MAX;
        int sum = 0; // 滑动窗口数值之和
        int i = 0; // 滑动窗口起始位置
        int subLength = 0; // 滑动窗口的长度
        for (int j = 0; j < nums.size(); j++) {
            sum += nums[j];
            // 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
            while (sum >= s) {
                subLength = (j - i + 1); // 取子序列的长度
                result = result < subLength ? result : subLength;
                sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == INT32_MAX ? 0 : result;
    }
};

3.(需要重做!) Spiral Matrix II

    class Solution {
        public int[][] generateMatrix(int n) {
            int[][] res = new int[n][n];
            int l = 0, r = n-1, t = 0, b = n-1;
            int num = 1, target = n*n;
            while(num <= target){
                for(int i = l; i <= r; ++i) res[l][i] = num++;
                ++t;
                for(int i = t; i <= b; ++i) res[i][r] = num++;
                --r;
                for(int i = r; i >= l; --i) res[b][i] = num++;
                --b;
                for(int i = b; i >= t; --i) res[i][l] = num++;
                ++l;
            }
            return res;
        }
    }

参考了答案的思路和格式,但码是自己写出来的,debug还挺费时间。这题需要重做!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值