算法训练营第二天|LeetCode209 长度最小的子数组、 LeetCode59 螺旋矩阵II、区间和、开发商购买土地

15 阅读2分钟

Leetcode209 长度最小的子数组

思路

滑动窗口的运用,使用Integer.MAX_VALUE也是很重要的方法

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

Leetcode59 螺旋矩阵II

这道题主要难度在于要头脑清醒,保证操作区间一直是左闭右开,矩阵中心的元素单独操作

class Solution {
    public int[][] generateMatrix(int n) {
        int startX = 0;
        int startY = 0;
        int offset = 1;
        int loop = 1;
        int count = 1;
        int i, j;
        int[][] result = new int[n][n];
        while(loop <= n / 2) {
            for(j = startY; j < n - offset; j++) {
                result[startX][j] = count++;
            }
            for(i = startX; i < n - offset; i++) {
                result[i][j] = count++;
            }
            for(; j > startY; j--) {
                result[i][j] = count++;
            }
            for(; i > startX; i--) {
                result[i][j] = count++;
            }
            startX++;
            startY++;
            offset++;
            loop++;
        }
        if(n % 2 == 1) {
            result[startX][startY] = count;
        }
        return result;
    }
}

区间和

题目描述

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

输入描述

第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间,直至文件结束。

输出描述

输出每个指定区间内元素的总和。

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] array = new int[n];
        int[] sumArray = new int[n];
        int presum = 0;
        for(int i = 0; i < n; i++) {
            array[i] = scanner.nextInt();
            presum += array[i];
            sumArray[i] += presum;
        }
        while(scanner.hasNextInt()) {
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            int sum = 0;
            if(a == 0) {
                sum = sumArray[b];
            } else {
                sum = sumArray[b] - sumArray[a - 1];
            }
            System.out.println(sum);
        }
        scanner.close();
    }
}

开发商购买土地

【题目描述】

在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。

现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。

然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。

为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。

注意:区块不可再分。

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[][] matrix = new int[n][m];
        int sum = 0;
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                matrix[i][j] = scanner.nextInt();
                sum += matrix[i][j];
            }
        }
        int[] horizontal = new int[n];
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                horizontal[i] += matrix[i][j];
            }
        }
        int[] vertical = new int[m];
        for(int j = 0; j < m; j++) {
            for(int i = 0; i < n; i++) {
                vertical[j] += matrix[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 - horizontalCut) - horizontalCut));
        }
        int verticalCut = 0;
        for(int j = 0; j < m; j++) {
            verticalCut += vertical[j];
            result = Math.min(result, Math.abs((sum - verticalCut) - verticalCut));
        }
        System.out.println(result);
        scanner.close();
    }
}