算法练习 | LeetCode977有序数组的平方、LeetCode209长度最小子数组、LeetCode59螺旋矩阵II(周末补)

80 阅读3分钟

LeetCode977有序数组的平方

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

题目链接:leetcode.cn/problems/sq…

解题思路

  • 看到这道题目的第一眼想到的方法是利用for循环加sort进行排序,但是这样时间复杂度就取决于sort为O(nlogn)
  • 由于这道题给出的数组是从两头向中间递减的,因此可以用双指针法分别指向第一个和最后一个数据,通过判断二者大小,将大的放进新创建的数组,并且该指针移动。

解题方法及注意事项

方法一 | for + sort()

var sortedSquares = function(nums) {
    for(let i = 0; i < nums.length; i++){
        nums[i] = nums[i] * nums[i];
    }
    nums.sort((a,b) => a - b);
    return nums;
};

方法二 | 双指针法

var sortedSquares = function(nums) {
    let res = [];
    res.length = nums.length;
    let left = 0;
    let right = nums.length - 1;
    for(let i = res.length - 1; i >= 0; i--){
        let leftN = nums[left] * nums[left];
        let rightN = nums[right] * nums[right];
        if(leftN < rightN){
            res[i] = rightN;
            right--;
        } else if(leftN >= rightN){
            res[i] = leftN;
            left++
        }
    }
    return res;
};

注意点

  • 这里一定要先将res的长度变为nums的相等长度,再从后向前进行遍历插入数组。

总结

说起来比较好笑,在写完第一种解法之后就想到了可以利用这里数组从两边向中间递减的规律,利用前后两个双指针解题,但由于总想着最简解法所以只考虑了在原数组的基础上进行移动,这里如果只是在原数组上更改就会变得非常复杂,所以说在解题的时候发现思路正确,但自己的实现却比较困难的时候要跳出自己原有的思维逻辑,去想想可不可以借用新的空间或者其他东西来解题。

LeetCode209长度最小子数组

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

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

题目链接:leetcode.cn/problems/mi…

解题思路

  • 这道题也是两种解题思路,第一种是暴力双层for循环,第一层循环参数为起始位置,第二层循环参数为终止位置,但是这种方法会将所有不满足条件的子数组都遍历出来,因此不太推荐
  • 第二种方法就是利用窗口滑动,先固定起始位置,终止位置从起点开始向前出发,当sum满足条件时停下并判断长度大小保留最小长度,起始位置再逐步向前并减去不包含的数据,当sum不满足条件时,终止位置再向前走,以此类推知道终止位置到数组重点且连续子数组不再满足条件时跳出循环。

解题方法及注意事项

方法一 | 暴力循环法

方法二 | 滑动窗口法

var minSubArrayLen = function(target, nums) {
    let start = 0;
    let sum = 0;
    let min = Infinity;
    for(let end = 0; end < nums.length; end++ ){
        sum += nums[end];
        while(sum >= target){
            let len = end - start + 1;
            if(len < min){
                min = len;
            }
            sum -= nums[start];
            start++;
        }
    }
    return min === Infinity ? 0 : min;
};

总结

其实这道题的重点还是在于掌握双指针,利用双指针来实现滑动窗口。