You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_06_3_week;
// 一个字符串s表示仓库的墙 与 货物,其中'|'表示墙,'*'表示货物。
// 给定一个起始下标start和一个终止下标end
// 找出子串中 被墙包裹的货物 数量
// 比如
// s = "|**|**|*"
// start = 1, end = 7
// start和end截出的子串是 "**|**|*"
// 被 '|'包裹的 '*' 有两个所以返回2
// 现在给定一系列的startstartIndices[]和对应一系列的end ,endIndices[]
// 返回每一对[start,end]的截出来的货物数量
// 数据规模:
// 字符串s长度<=10^5
// startIndices长度 == endIndices长度 <=10^5
public class Code04_StarNumber {
// 解法
// 生成每个位置左边离这个位置最近的'|'在哪left数组
// 生成每个位置右边离这个位置最近的'|'在哪right数组
// 生成每个位置左边一共有几个'*'sum数组
// 比如s如下第一行是字符串第二行是下标
// | * * | * * | *
// 0 1 2 3 4 5 6 7
// 生成的left数组第一行是值第二行是下标
// 0 0 0 3 3 3 6 6
// 0 1 2 3 4 5 6 7
// 生成的right数组第一行是值第二行是下标
// 0 3 3 3 6 6 6 -1
// 0 1 2 3 4 5 6 7
// 生成的sum数组第一行是值第二行是下标
// 0 1 2 2 3 4 4 5
// 0 1 2 3 4 5 6 7
// 比如start = 1, end = 7
// 找到start右边最近的'|'在哪根据right直接查到在3位置
// 找到end左边最近的'|'在哪根据left直接查到在6位置
// 1~7范围上被墙包裹*的个数 = 3~6范围上被墙包裹*的个数
// 3~6范围上被墙包裹*的个数 = sum[6] - sum[2] = 2
public static int[] number(String s, int[] starts, int[] ends) {
char[] str = s.toCharArray();
int n = str.length;
int[] left = new int[n];
int[] right = new int[n];
int[] sum = new int[n];
int pre = -1;
int num = 0;
for (int i = 0; i < n; i++) {
pre = str[i] == '|' ? i : pre;
num += str[i] == '*' ? 1 : 0;
left[i] = pre;
sum[i] = num;
}
pre = -1;
for (int i = n - 1; i >= 0; i--) {
pre = str[i] == '|' ? i : pre;
right[i] = pre;
}
int m = starts.length;
int[] ans = new int[m];
for (int i = 0; i < m; i++) {
ans[i] = stars(starts[i], ends[i], left, right, sum);
}
return ans;
}
public static int stars(int start, int end, int[] l, int[] r, int[] s) {
int left = r[start];
int right = l[end];
if (left == -1 || right == -1 || (left >= right)) {
return 0;
}
return left == 0 ? s[right] : (s[right] - s[left - 1]);
}
public static void main(String[] args) {
String s = "|**|**|*";
int[] a = new int[] { 0, 1, 3, 4 };
int[] b = new int[] { 7, 7, 6, 5 };
int[] arr = number(s, a, b);
for (int ans : arr) {
System.out.println(ans);
}
}
}