Skip to content

Commit f17f31b

Browse files
committed
weekly contest 361
1 parent 1ef5361 commit f17f31b

File tree

3 files changed

+396
-1
lines changed

3 files changed

+396
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ leetcode url: <https://leetcode.cn/u/cctest/>
66

77

88

9+
* 🐼 [weekly contest 361](src/main/java/weekly/wk361.java) 枚举 | 枚举 | 前缀和 | 树上倍增+LCA
910
* 🐼 [weekly contest 360](src/main/java/weekly/wk360.java) 贪心 | 哈希 | 贪心+二进制 | 树上倍增
1011
* 🐼 [weekly contest 359](src/main/java/weekly/wk359.java) 模拟 | 贪心 | 分组+dp | 分组+双指针
1112
* 🐼 [weekly contest 358](src/main/java/weekly/wk358.java) 模拟 | 链表 | 滑动窗口 | 质数分解+单调栈+快速幂
@@ -72,7 +73,7 @@ leetcode url: <https://leetcode.cn/u/cctest/>
7273
* 🐶 [weekly contest 290](src/main/java/weekly/wk290.java)
7374
* 🐭 [weekly contest 280](src/main/java/weekly/wk289.java)
7475

75-
76+
* 🐸 [biweekly contest 112](src/main/java/weekly/wkb112.java) 哈希 | 哈希 | 哈希+滑窗 | 组合数
7677
* 🐸 [biweekly contest 111](src/main/java/weekly/wkb111.java) 遍历 | 贪心+双指针 | 前缀和、dp | 数位dp
7778
* 🐸 [biweekly contest 110](src/main/java/weekly/wkb110.java) 遍历 | 链表 | 哈希 | 排序+dp
7879
* 🐸 [biweekly contest 109](src/main/java/weekly/wkb109.java) 模拟 | 模拟 | dp | 01背包/记忆化搜索

src/main/java/weekly/wk361.java

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
package weekly;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
public class wk361 {
10+
11+
//枚举
12+
public int countSymmetricIntegers(int low, int high) {
13+
14+
int ans = 0;
15+
for (int i = low; i <= high; i++) {
16+
int num = i;
17+
List<Integer> list = new ArrayList<>();
18+
while (num > 0) {
19+
list.add(num % 10);
20+
num /= 10;
21+
}
22+
if (list.size() % 2 == 1) continue;
23+
int sum = 0;
24+
for (int j = 0; j < list.size() / 2; j++) {
25+
sum += list.get(j);
26+
}
27+
for (int j = list.size() / 2; j < list.size(); j++) {
28+
sum -= list.get(j);
29+
}
30+
if (sum == 0) ans++;
31+
}
32+
return ans;
33+
}
34+
35+
36+
//枚举后缀
37+
public int minimumOperations(String num) {
38+
int ans = num.length();
39+
//变成0
40+
if (num.contains("0")) {
41+
ans = num.length() - 1;
42+
}
43+
44+
ans = Math.min(ans, help(num, new char[]{'5', '2'}));
45+
ans = Math.min(ans, help(num, new char[]{'0', '5'}));
46+
ans = Math.min(ans, help(num, new char[]{'5', '7'}));
47+
ans = Math.min(ans, help(num, new char[]{'0', '0'}));
48+
return ans;
49+
}
50+
51+
int help(String num, char[] arr) {
52+
int index = 0;
53+
int ans = 0;
54+
for (int i = num.length() - 1; i >= 0; i--) {
55+
if (num.charAt(i) == arr[index]) {
56+
index++;
57+
if (index >= arr.length) break;
58+
} else {
59+
ans++;
60+
}
61+
}
62+
if (index < arr.length) return Integer.MAX_VALUE;
63+
return ans;
64+
}
65+
66+
67+
//前缀和
68+
static public long countInterestingSubarrays(List<Integer> nums, int modulo, int k) {
69+
int[] pre = new int[nums.size() + 1];
70+
for (int i = 0; i < nums.size(); i++) {
71+
pre[i + 1] = pre[i] + (nums.get(i) % modulo == k ? 1 : 0);
72+
}
73+
74+
Map<Integer, Integer> map = new HashMap<>();
75+
76+
long ans = 0;
77+
for (int i = 0; i < pre.length; i++) {
78+
int num = pre[i];
79+
ans += map.getOrDefault((num %modulo - k + modulo) % modulo,0);
80+
map.put(num % modulo, map.getOrDefault(num % modulo, 0) + 1);
81+
}
82+
return ans;
83+
}
84+
85+
86+
/* static public long countInterestingSubarrays(List<Integer> nums, int modulo, int k) {
87+
int[][] check = new int[nums.size()][2];
88+
int pre = 0;
89+
for (int i = 0; i < nums.size(); i++) {
90+
int num = nums.get(i);
91+
if (num % modulo == k) {
92+
check[i][0] = 1;
93+
check[i][1] = pre;
94+
pre = 0;
95+
} else {
96+
pre++;
97+
}
98+
}
99+
100+
List<int[]> list = new ArrayList<>();
101+
long ans = 0;
102+
pre = 0;
103+
for (int i = 0; i < nums.size(); i++) {
104+
int sum = 0;
105+
if (check[i][0] > 0) {
106+
int left = list.size() - modulo;
107+
list.add(new int[]{i, (left >= 0 && left < list.size() ? list.get(left)[1] : 0) + pre + 1});
108+
pre = 0;
109+
} else {
110+
pre++;
111+
if (k == 0) sum = pre;
112+
}
113+
int j = k == 0 ? list.size() - modulo : list.size() - k;
114+
if (j >= 0) sum += list.get(j)[1];
115+
ans += sum;
116+
}
117+
return ans;
118+
}*/
119+
120+
121+
122+
//双上倍增+lca
123+
public int[] minOperationsQueries(int n, int[][] edges, int[][] queries) {
124+
List<int[]>[] g = new ArrayList[n];
125+
Arrays.setAll(g, e -> new ArrayList<>());
126+
for (int [] e : edges) {
127+
int x = e[0], y = e[1], w = e[2] - 1;
128+
g[x].add(new int[]{y, w});
129+
g[y].add(new int[]{x, w});
130+
}
131+
132+
int m = 32 - Integer.numberOfLeadingZeros(n); // n 的二进制长度
133+
int [][] pa = new int[n][m];
134+
for (int i = 0; i < n; i++) {
135+
Arrays.fill(pa[i], -1);
136+
}
137+
int [][][] cnt = new int[n][m][26];
138+
int [] depth = new int[n];
139+
//求出 父节点、cnx[x][0],深度数组
140+
dfs(0, -1, g, pa, cnt, depth);
141+
142+
//倍增求每个点的2的i次方的次数以及位置
143+
for (int i = 0; i < m - 1; i++) {
144+
for (int x = 0; x < n; x++) {
145+
int p = pa[x][i];
146+
if (p != -1) {
147+
int pp = pa[p][i];
148+
pa[x][i + 1] = pp;
149+
for (int j = 0; j < 26; j++) {
150+
cnt[x][i + 1][j] = cnt[x][i][j] + cnt[p][i][j];
151+
}
152+
}
153+
}
154+
}
155+
156+
//计算结果
157+
int [] ans = new int[queries.length];
158+
for (int qi = 0; qi < queries.length; qi++) {
159+
int x = queries[qi][0], y = queries[qi][1];
160+
int pathLen = depth[x] + depth[y];
161+
//倍增求lca,顺便计算次数
162+
int [] cw = new int[26];
163+
//置换深度大小,让y始终是深的
164+
if (depth[x] > depth[y]) {
165+
int temp = x;
166+
x = y;
167+
y = temp;
168+
}
169+
170+
// 让 y 和 x 在同一深度,避免在同一个路径上
171+
for (int k = depth[y] - depth[x]; k > 0; k &= k - 1) {
172+
int i = Integer.numberOfTrailingZeros(k);
173+
int p = pa[y][i];
174+
for (int j = 0; j < 26; ++j) {
175+
cw[j] += cnt[y][i][j];
176+
}
177+
y = p;
178+
}
179+
if (y != x) {
180+
for (int i = m - 1; i >= 0; i--) {
181+
int px = pa[x][i];
182+
int py = pa[y][i];
183+
//相等表示跳过了
184+
if (px != py) {
185+
for (int j = 0; j < 26; j++) {
186+
cw[j] += cnt[x][i][j] + cnt[y][i][j];
187+
}
188+
x = px;
189+
y = py; // x 和 y 同时上跳 2^i 步
190+
}
191+
}
192+
for (int j = 0; j < 26; j++) {
193+
cw[j] += cnt[x][0][j] + cnt[y][0][j];
194+
}
195+
x = pa[x][0];
196+
}
197+
198+
int lca = x;
199+
pathLen -= depth[lca] * 2;
200+
int maxCw = 0;
201+
for (int i = 0; i < 26; i++) {
202+
maxCw = Math.max(maxCw, cw[i]);
203+
}
204+
ans[qi] = pathLen - maxCw;
205+
}
206+
return ans;
207+
}
208+
209+
private void dfs(int x, int fa, List<int[]>[] g, int[][] pa, int[][][] cnt, int[] depth) {
210+
pa[x][0] = fa;
211+
for (int [] e : g[x]) {
212+
int y = e[0], w = e[1];
213+
if (y != fa) {
214+
cnt[y][0][w] = 1;
215+
depth[y] = depth[x] + 1;
216+
dfs(y, x, g, pa, cnt, depth);
217+
}
218+
}
219+
}
220+
221+
222+
}

0 commit comments

Comments
 (0)