算法修炼Day02|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

143 阅读2分钟

题目:977. 有序数组的平方 - 力扣(LeetCode)

思考:

解法一:平方排序,暴力实现。

解法二:双指针。申请结果集ans数组,遍历原数组前后比较元素的平方,较大值赋值给新数组对应的索引下标,倒序赋值。

代码实现:

// 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) {
        // 双指针:前后两个值中选出最大的往后排。O(n)的复杂度需要创建一个新的结果集,想在原数组中进行更新需要O(n^2)的复杂度。
        int left = 0;
        int right = nums.length - 1;
        int[] ans = new int[nums.length];
        int j = ans.length - 1;
        while (left <= right) {
            if (nums[right] * nums[right] >= nums[left] * nums[left]) {
                ans[j--] = nums[right] * nums[right];
                right--;
            } else if (nums[right] * nums[right] < nums[left] * nums[left]) {
                ans[j--] = nums[left] *nums[left];
                left++;
            }
        }
        return ans;
    }
}


题目:209. 长度最小的子数组 - 力扣(LeetCode)

思考:

最短连续子数组大于等于target的值。滑动窗口:右侧进元素,左侧出元素。

代码实现:

// 超时
// class Solution {
//     public int minSubArrayLen(int target, int[] nums) {
//         int ans = Integer.MAX_VALUE;
//         for (int i = 0; i < nums.length; i++) { // 遍历定位
//             int mid = 0; // 连续子数组和的初始值
//             for (int j = i; j < nums.length; j++) { // 获取从 i 位置起到 j 位置的和 >= target 的结果值,取较小值: ans
//                 mid += nums[j];
//                 if (mid >= target) {
//                     ans = Math.min(ans, j - i + 1);
//                     break;
//                 }
//             }
//         }
//         return ans == Integer.MAX_VALUE ? 0 : ans;
//     }
// }

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // 滑动窗口:右侧加入元素,左侧弹出元素
        int left = 0, right = 0;
        int ans = Integer.MAX_VALUE; // 最少元素数!
        int sum = 0;
        while (left <= right && right < nums.length) {
          sum += nums[right];
          while (sum >= target) { // 连续缩减区间
            ans = Math.min(ans, right - left + 1);
            sum -= nums[left];
            left++;
          }
          right++;
        }
        return ans == Integer.MAX_VALUE ? 0 : ans;
    }
}

题目:59. 螺旋矩阵 II - 力扣(LeetCode)

思考:

模拟题:四条边分别模拟变化、收缩。在那个边那个边上对应的竖向值或横向值不变。

代码实现:

class Solution {
    public int[][] generateMatrix(int n) {
        int l = 0, r = n - 1, t = 0, b = n - 1;
        int[][] ans = new int[n][n];
        // 模拟题
        int start = 1, tar = n * n;
        while (start <= tar) {
            for (int i = l; i <= r; i++) ans[t][i] = start++; // 上:从左到右
            t++;
            for (int i = t; i <= b; i++) ans[i][r] = start++; // 右:从上到下
            r--;
            for (int i = r; i >= l; i--) ans[b][i] = start++; // 下:从右到左
            b--;
            for (int i = b; i >= t; i--) ans[i][l] = start++; // 左:从下到上
            l++;
        }
        return ans;
    }
}