代码随想录训练营-数组part02

78 阅读2分钟

代码随想录训练营-数组part02

解题思路-- 977 有序数组的平方

题目特征: 有序数组经过转换,变化为有序数组

解题思考:

  1. 双指针遍历,左右两指针进行对比,按照对比后结果,按顺序存放至新数组
  2. 对比成功的指针进行移动,重新进行step1
  3. 当两指针进行汇合时进行最后一次对比
class Solution {
    public int[] sortedSquares(int[] nums) {
        // 数组有序,正负皆有
        // 重新定义数组进行存储,老数组双指针遍历,取大的数据倒序放到新的数组中
        int leftPoint = 0;
        int rightPoint = nums.length -1;
        int[] newNums = new int[nums.length];
        int index = nums.length -1;
        while(leftPoint <= rightPoint){
            int leftNum = nums[leftPoint] * nums[leftPoint];
            int rightNum = nums[rightPoint] * nums[rightPoint];
            if (leftNum > rightNum){
                newNums[index] = leftNum;
                leftPoint++;
            }else{
                newNums[index] = rightNum;
                rightPoint--;
            }
            index--;
        }
        return newNums;
    }
}

解题思路-- 209.长度最小的子数组

题目特征: 有序数组中查找符合条件的最优子数组

解题思考:

  1. 数组优先考虑双指针
  2. 母数组进行符合条件的子数组查找,优先考虑滑动窗口
  3. 滑动窗口找好追外层for循环采用右指针
  4. for中套取while进行左指针滑动
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        // 滑动窗口解法 双指针
        // 循环右指针,累积左指针至右指针之间的数组元素和
        // 当数组元素和>target时,记录当前最大长度j-i+1,左指针开始右移
        // 注意  因为右指针相对静止,所以要在for循环中加while进行左指针遍历
        int leftPoint = 0;
        int result = Integer.MAX_VALUE;
        int sum = 0;
        for (int rightPoint = 0; rightPoint < nums.length ; rightPoint++ ){
            sum += nums[rightPoint];
            while(sum >= target){
                result = Math.min(rightPoint - leftPoint +1, result);
                sum = sum - nums[leftPoint];
                leftPoint++;
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

解题思路-- 59.螺旋矩阵II

题目特征: 有序自然整数组成二维数组

解题思考:

  1. 此类问题基本上考虑数值的存放位置
  2. 每条线段的处理逻辑应相同 例如均采用左闭右开
  3. 找好每条线段的起始位置和边界条件即可
  4. 每一圈循环的起始位置和边界条件谨慎考虑
class Solution {
    public int[][] generateMatrix(int n) {
       int[][] array =  new int[n][n];
       // 当前圈数
       int loop = 0;
       // 当前待赋值数据
       int currentNum = 1;
       // 每圈初始行位置
       int start =0;
       // 行初始值
       int i=0;
       // 列初始值
       int j=0;
       // 每次遍历为一圈
        while(loop++ < n/2){
            // 遍历原则为左闭右开 [)
            // 第一行 j为当前列 遍历 n-loop为列的开区间上限
            for (j=start; j<n-loop;j++){
                array[start][j] = currentNum++;
            }
            // 最后一列
            for(i = start; i< n-loop; i++){
                array[i][j] = currentNum++;
            }
            // 最后一行
            for(;j  >= loop;j--){
                array[i][j] = currentNum++;
            }
            // 第一列
            for(;i >= loop; i--){
                array[i][j] = currentNum++;
            }
            start ++;
        }

        // 最中间元素
        if(n%2 == 1){
            array[n/2][n/2] = currentNum;
        }
        return array;
    }
}