5.28 数组

This commit is contained in:
zhangsan 2025-05-28 11:10:45 +08:00
parent 620e720dba
commit 6dc7b98fe0
5 changed files with 220 additions and 0 deletions

View File

@ -0,0 +1,32 @@
package array;
/**
* 题目209. 长度最小的子数组 (minSubArrayLen)
* 描述给定一个含有 n 个正整数的数组和一个正整数 target
*
* 找出该数组中满足其总和大于等于 target 的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr] 并返回其长度如果不存在符合条件的子数组返回 0
*
* 示例 1
输入target = 7, nums = [2,3,1,2,4,3]
输出2
解释子数组 [4,3] 是该条件下的长度最小的子数组
* 链接https://leetcode.cn/problems/minimum-size-subarray-sum/
*/
//大致思路想到了 代码不会写
public class MinSubArrayLen {
public int minSubArrayLen(int s, int[] nums) {
int left = 0;
int sum = 0;
int result = Integer.MAX_VALUE;
for (int right = 0; right < nums.length; right++) {
sum += nums[right];
while (sum >= s) {
result = Math.min(result, right - left + 1);
sum -= nums[left++];
}
}
return result == Integer.MAX_VALUE ? 0 : result;
}
}

View File

@ -0,0 +1,63 @@
package array;
import java.util.*;
import java.io.*;
/**
* 题目描述
*
* 给定一个整数数组 Array请计算该数组在每个指定区间内元素的总和
*
* 输入描述
*
* 第一行输入为整数数组 Array 的长度 n接下来 n 每行一个整数表示数组的元素随后的输入为需要计算总和的区间下标ab b > = a直至文件结束
* 输入示例
* 5
* 1
* 2
* 3
* 4
* 5
* 0 1
* 1 3
*输出
* 3
* 9
* 输出每个指定区间内元素的总和
*/
public class RangeSum {
public static void main(String[] args) throws IOException {
// 快速 IO
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String line;
// 1读数组长度
line = br.readLine();
if (line == null) return;
int n = Integer.parseInt(line.trim());
// 2读数组元素并构造前缀和
long[] prefix = new long[n + 1];
for (int i = 0; i < n; i++) {
line = br.readLine();
if (line == null) throw new IOException("Unexpected EOF when reading array");
prefix[i + 1] = prefix[i] + Long.parseLong(line.trim());
}
// 3依次读查询直到 EOF
// 每行两个整数 a, b (0 a b < n)
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.isEmpty()) continue;
StringTokenizer st = new StringTokenizer(line);
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
// 区间和 = prefix[b+1] - prefix[a]
long sum = prefix[b + 1] - prefix[a];
out.println(sum);
}
out.flush();
}
}

View File

@ -0,0 +1,33 @@
package array;
/**
* 题目 977. 有序数组的平方 (SortedSquares)
* 描述给你一个按 非递减顺序 排序的整数数组 nums返回 每个数字的平方 组成的新数组要求也按 非递减顺序 排序
*
* 示例 1
输入nums = [-4,-1,0,3,10]
输出[0,1,9,16,100]
解释平方后数组变为 [16,1,0,9,100]
排序后数组变为 [0,1,9,16,100]
* 链接https://leetcode.cn/problems/squares-of-a-sorted-array/
*/
public class SortedSquares {
public int[] sortedSquares(int[] nums) {
int right = nums.length - 1;
int left = 0;
int[] result = new int[nums.length];
int index = result.length - 1;
while (left <= right) {
if (nums[left] * nums[left] > nums[right] * nums[right]) {
// 正数的相对位置是不变的 需要调整的是负数平方后的相对位置
result[index--] = nums[left] * nums[left];
++left;
} else {
result[index--] = nums[right] * nums[right];
--right;
}
}
return result;
}
}

View File

@ -0,0 +1,43 @@
package greedy;
/**
* 题目 738. 单调递增的数字 (monotoneIncreasingDigits)
* 描述当且仅当每个相邻位数上的数字 x y 满足 x <= y 我们称这个整数是单调递增的
*
* 给定一个整数 n 返回 小于或等于 n 的最大数字且数字呈 单调递增
* 示例 1
输入: n = 2332
输出: 2299
* 链接https://leetcode.cn/problems/monotone-increasing-digits/
*/
//不会
public class MonotoneIncreasingDigits {
/**
* 一旦发现某一位数字比右边一位大就必须在这一位或更靠左的一位上借位将该位数字减一而后面的所有位都置为 9以保证单调递增同时又尽可能大
从右往左 对每一对相邻位做检查
只要发现 d[i-1] > d[i]就把 d[i-1]--并把标记 mark = i表示从这里开始以后都要变成 9
整个遍历不要 break而是继续往左走处理可能连锁的多次借位
最后把 mark 及以后的所有位都设成 '9'
* @param n
* @return
*/
public int monotoneIncreasingDigits(int n) {
char[] d = String.valueOf(n).toCharArray();
int mark = d.length;
// 1) 从右往左遇到下降就借位并记录位置
for (int i = d.length - 1; i > 0; --i) {
if (d[i-1] > d[i]) {
d[i-1]--; // 借位
mark = i; // 标记后续全改成 9
}
}
// 2) mark 到末尾全设为 '9'
for (int i = mark; i < d.length; ++i) {
d[i] = '9';
}
// 3) 拼回整数返回
return Integer.parseInt(new String(d));
}
}

View File

@ -0,0 +1,49 @@
package matrix;
import java.util.List;
/**
* 题目59. 螺旋矩阵 II (generateMatrix)
* 描述给你一个正整数 n 生成一个包含 1 n2 所有元素且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix
*
* 示例 1
输入n = 3
输出[[1,2,3],[8,9,4],[7,6,5]]
* 链接https://leetcode.cn/problems/spiral-matrix-ii/
*/
public class GenerateMatrix {
public int[][] generateMatrix(int n) {
int[][]res=new int[n][n];
int index=1;
int top=0,left=0,right=n-1,bottom=n-1;
while (top<=bottom&&left<=right){
for (int i = left; i <= right; i++) {
res[top][i]=index;
index++;
}
top++;
for (int i = top; i <= bottom; i++) {
res[i][right]=index;
index++;
}
right--;
if (top <= bottom) {
for (int i = right; i >= left; i--) {
res[bottom][i] = index;
index++;
}
bottom--;
}
if(left <= right) {
for (int i = bottom; i >= top; i--) {
res[i][left] = index;
index++;
}
left++;
}
}
return res;
}
}