代码随想录第二天 | 977.有序数组的平方、209.长度最小的子数组、59.螺旋矩阵II

文章介绍了两种算法问题的解决方案:一是给定有序数组,计算每个元素的平方后保持非递减排序,可以使用暴力方法或双指针法;二是寻找和大于等于目标值的最短连续子数组,可通过暴力法或滑动窗口法解决。另外,还讲解了如何生成顺时针螺旋排列的矩阵。
摘要由CSDN通过智能技术生成

977.有序数组的平方

有序数组的平方 力扣链接

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

示例 1:

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

示例 2:

输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]

思路:

  1. 暴力解法

对数组各项进行平方,再用 冒泡排序 或者 Arrays.sort() 排序;(注:该算法复杂度为O(n+nlogn) )

代码实现:

// import java.util.Arrays;

class Solution {
       public int[] sortedSquares(int[] nums) {
            for (int i = 0; i < nums.length; i++) {
            nums[i] *= nums[i];
        }
            //Arrays.sort(nums);
            for (int i = 0; i < nums.length - 1; i++) {
            for (int j = 0; j < nums.length - 1; j++) {
                if (nums[j + 1] < nums[j]) {
                    int t = nums[j];
                    nums[j] = nums[j + 1];
                    nums[j + 1] = t;
                }
            }
        }
        return nums;
    }
}

  1. 双指针法

数组本身是有序的 但是因为负数的平方可能会很大 大到超过正数的平方

因此,数组的最大值要么是最左端的数据 要么是最右端的数据

我们定义一个和原数组一样长度的新的数组

再定义两个新的量代表指针 变量 left 表示初始位置 变量 right 表示终末位置

将原数组 left 指向的值的平方 和 right 指向的值的平方进行比较 将大的放到新数组的终末位置

然后 left 或 right 进行值的变化 并重复上一步 将大的值放到新数组的新的终末位置

如果A[left] * A[left] < A[right] * A[right] 那么result[index--] = A[right] * A[right]; 。

如果A[left] * A[left] >= A[right] * A[right] 那么result[index--] = A[left] * A[left]; 。

代码实现:

class Solution {
   public int[] sortedSquares(int[] nums) {
            int[] arr = new int[nums.length];
            int left = 0;
            int right = nums.length - 1;
            int index = right;
            while(left <= right){
                if(nums[left]*nums[left] < nums[right]*nums[right]){
                    arr[index--] = nums[right]*nums[right--];
                }else{
                    arr[index--] = nums[left]*nums[left++];
                }
            }
            return arr;
        }
}

209.长度最小的子数组

长度最小的子数组 力扣链接

题目:

给定一个含有 n 个正整数的数组和一个正整数 target 。

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

示例 1:

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

示例 2:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

思路

 1.暴力法

代码如下:

class Solution {
        public int minSubArrayLen(int target, int[] nums) {
            int result = Integer.MAX_VALUE; // 最终返回的数据
            int sum = 0;                    // 子序列的数值之和
            int sublength = 0;              // 子序列的长度
            for(int i = 0;i < nums.length;i++){          // 设置子序列起点为i
                sum = 0;
                for(int j = i ;j < nums.length;j++){     // 设置子序列终止位置为j
                    sum += nums[j];
                    if(sum >= target){
                        sublength = j - i + 1;
                        result = result < sublength ? result : sublength;
                        break;                            // 符合条件即可 break 跳出循环
                    }
                }
            }
            return result == Integer.MAX_VALUE ? 0 : result;  // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        }
    }

时间复杂度:O(n^2)

 2.滑动窗口法

代码如下:

class Solution1 {
        public int minSubArrayLen(int target, int[] nums) {
            int left = 0;
            int sum = 0;
            int result = Integer.MAX_VALUE;
            for(int right = 0; right < nums.length; right++){
                sum += nums[right];
                while(sum >= target){
                    result = Math.min(result,right - left + 1);
                    sum -= nums[left++];
                }
            }
            return result == Integer.MAX_VALUE ? 0 : result;
        }
    }

时间复杂度:O(n)


59.螺旋矩阵II

螺旋矩阵 II 力扣链接

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

需要尤其注意边界条件的选择

我们设左边界为 l 有边界 为 r 上边界为 t 下边界为 b

对矩阵进行顺时针的边界旋转移动

代码如下:

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

加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值