代码随想录算法训练营第二天| 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();
}
}