题目:
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其总和大于等于 target
的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度**。**如果不存在符合条件的子数组,返回 0
。
思路:
滑动窗口,始终保持在边界取临界值进行比较
代码:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int sum = 0;
int res = Integer.MAX_VALUE;
for(int i=0,j=-1;i<nums.length;i++){
sum+=nums[i];
while(sum>=target){
int l = i-j;
sum-= nums[++j];
res = res>l?l:res;
}
}
if(res==Integer.MAX_VALUE) return 0;
else return res;
}
}
题目:
给你一个正整数 n
,生成一个包含 1
到 n2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
。
思路:
模拟,需要找到每一圈以及各圈间跳转的规律
代码:
class Solution {
public int[][] generateMatrix(int n) {
int[][] res = new int[n][n];
int len = n-1;
int num = 1;
int mid = n/2;
for(int i=0;i<mid;i++){
int x=i,y=i;
while(x<len){
res[y][x++] = num++;
}
while(y<len){
res[y++][x] = num++;
}
while(x>i){
res[y][x--] = num++;
}
while(y>i){
res[y--][x] = num++;
}
len-=1;
}
if(n%2==1){
res[mid][mid]=num;
}
return res;
}
}
题目:
给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。
思路:
前缀和相减得中间区间
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int[] pre = new int[n+1];
for(int i=1;i<=n;i++) {
pre[i] = pre[i-1]+s.nextInt();
}
while(s.hasNextInt()) {
int a = s.nextInt();
int b = s.nextInt();
System.out.println(pre[b+1]-pre[a]);
}
}
}
题目:
在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。
现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。
然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。
为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。注意:区块不可再分。
思路:
每次行/列结束统计一下切分,可以看作优化的前缀和(得到后区间,再减前区间)
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = s.nextInt();
int[][] region = new int[n][m];
int sum =0;
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
sum+=(region[i][j] = s.nextInt());
}
}
int res = Integer.MAX_VALUE;
int tmp = 0;
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
tmp+=region[i][j];
}
int cur = Math.abs(sum-2*tmp);
if(cur<res){
res = cur;
}
}
tmp = 0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
tmp+=region[j][i];
}
int cur = Math.abs(sum-2*tmp);
if(cur<res){
res = cur;
}
}
System.out.println(res);
}
}
题目:
我们用xi表示第i年年初池塘中藻类植物的总重量,那么池塘中藻类植物的发展满足这个规律xi+1 =r * xi - d。现在给你r, d, x2024,请你计算未来十年里每年年初池塘中藻类植物的总重量。
思路:
按照公式循环递推
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int r = s.nextInt();
int d = s.nextInt();
long x = s.nextInt();
for(int i=0;i<10;i++) {
x = r*x-d;
System.out.println(x);
}
}
}
题目:
有一款叫做吃豆人(Pacman)的游戏有许多粉丝,这些粉丝只要看到看到任何包含"pacman"作为子串的字符串就会变得非常激动。现在你有一个长度为n的字符出s,你每次可以将其中一个字母换为另外一个字母,请问你最少需要替换多少次才能使其不含有"pacman"作为子串?
思路:
统计计数每项改一个为其他未出现的字符
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
String str = s.next();
int count = 0;
int index = 0;
while((index = str.indexOf("pacman",index))!=-1) {
count++;
index+=6;
}
System.out.println(count);
}
}
题目:
给出一个仅由大写字母"AB"构成的字符串s,请你求出s中包含’A’和’B’个数相同的连续区间的最长长度。
思路:
和等值前缀做差即可得到符合条件的子串
代码:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int res = 0;
String str = s.next();
int l = str.length();
int pre = 0;
int[] hash = new int[l*2+1];
Arrays.fill(hash,-1);
hash[l] = 0;
int i = 1;
for(char c:str.toCharArray()) {
if(c=='A') pre++;
else pre--;
int x = pre+l;
if(hash[x]!=-1) {
int len = i-hash[x];
res = res>len?res:len;
}else {
hash[x] = i;
}
i++;
}
System.out.println(res);
}
}
数组篇练习了二分,双指针,滑动窗口,前缀和
数组的题目需要谨慎的处理索引的边界条件
数组元素不能删除,只能覆盖,想要真删除需要创建新的空间依次复制保留值,效率较低
代码随想录算法训练营第一天