代码随想录算法训练营第二天| 209.长度最小子数组 59.螺旋矩阵 区间和 开发商购买土地

209.长度最小子数组

  • result最初为nums.length + 1 才能在最后判断不存在的情况且不会遗漏与数组等长的情况
  • 滑动窗口:右指针代表窗口起始位置,左指针代表窗口结束位置
  • 时间复杂度 O(n) : 每个数据被操作两次,进窗口一次,出窗口一次
class Solution {
    public int minSubArrayLen(int target, int[] nums) {
    	//result比长度大一可以判断出result是否不存在
        int result = nums.length + 1;
        int right = 0;
        int left = 0;
        int sum = 0;
        for(left = 0; left < nums.length; left++){
            sum += nums[left];
            while(sum >= target){
                int subL = left - right + 1;
                result = Math.min(result, subL);
                sum -= nums[right];
                right++;
            }
        }
        return result > nums.length ? 0 : result;
    }
}

59.螺旋矩阵

转几圈:n/2

class Solution {
    public int[][] generateMatrix(int n) {

        int[][] nums = new int[n][n];

        //nums[starti][startj]表示每圈起始位置
        int starti = 0, startj = 0;

        //loop表示第几圈;n-loop为每圈最后一排/列下标
        int loop = 1; 

        //i,j循环变量表示填充位置
        int i = 0, j = 0;

        //count表示填入数
        int count = 1;

        //每一圈填四条边,左闭右开
        while(loop <=  n / 2){
            //确定起始点
            i = starti;
            j = startj;

            //顶边j变
            for(; j < n - loop; j++){
                nums[i][j] = count++;
            }
            //右边i变
            for(; i < n - loop; i++){
                nums[i][j] = count++;
            }
            //底边j变
            for(; j > startj; j--){
                nums[i][j] = count++;
            }
            //左边i变
            for(; i > starti; i--){
                nums[i][j] = count++;
            }

            //改变起始位置
            starti++;
            startj++;
            //改变圈数
            loop++;
        }
        
        //单独判定奇数情况
        if(n % 2 == 1){
            nums[starti][startj] = count;
        }

        return nums;
    }
}

区间和

前缀和思想: 提供预处理数组,求所有前缀和

import java.util.Scanner;

public class Main{
    public static void main(String[] args){

        Scanner scanner = new Scanner(System.in);

        int n = scanner.nextInt();
        int[] num = new int[n];
        int[] p = new int[n];
        int presum = 0;

        for(int i = 0; i < n; i++){
            num[i] = scanner.nextInt();
            presum += num[i];
            p[i] = presum;
        }

        while(scanner.hasNextInt()){
            int a = scanner.nextInt();
            int b = scanner.nextInt();

            int sum;
            if(a == 0){
                System.out.println(p[b]);
            }else{
                System.out.println(p[b] - p[a - 1]);
            }
        }

        scanner.close();
    }
}

开发商购买土地

前缀和思想: 分别求预处理数组,行和与列和,再进行比较

import java.util.Scanner;

public class Main {
    public static void main(String[] args){
         Scanner scanner = new Scanner(System.in);

         int n = scanner.nextInt();
         int m = scanner.nextInt();
         int num[][] = new int[n][m];
         int sum = 0;

         for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                num[i][j] = scanner.nextInt();
                sum += num[i][j];
            }
         }

         int[] horizontal = new int[n];
         for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                horizontal[i] += num[i][j];
            }
         }

         int[] vertical = new int[m];
         for(int j = 0; j < m; j++){
            for(int i = 0; i < n; i++){
                vertical[j] += num[i][j];
            }
         }

         int result = Integer.MAX_VALUE;

         int horizontalCut = 0;
         for(int i = 0; i < n; i++){
            horizontalCut += horizontal[i];
            result = Math.min(result, Math.abs(sum - 2 * horizontalCut));
         }

         int verticalCut = 0;
         for(int j = 0; j < m; j++){
            verticalCut += vertical[j];
            result = Math.min(result, Math.abs(sum - 2 * verticalCut));
         }

        System.out.println(result);
        scanner.close();
    }
}