Skip to content

Commit 6970146

Browse files
committed
weekly contest 339
1 parent fdc91ce commit 6970146

File tree

3 files changed

+378
-0
lines changed

3 files changed

+378
-0
lines changed

README.md

+2
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 339](src/main/java/weekly/wk339.java) 模拟 | 哈希 | 贪心 | 平衡树
910
* ☀️ [weekly contest 338](src/main/java/weekly/wk338.java) 贪心 | 谈心 | 前缀和+二分 | 拓扑排序
1011
* ☀️ [weekly contest 337](src/main/java/weekly/wk337.java) 模拟 | 模拟 | 回溯 | 同余分组
1112
* 🐎️ [weekly contest 336](src/main/java/weekly/wk336.java) 模拟 | 排序 | 异或前缀和 | 贪心
@@ -53,6 +54,7 @@ leetcode url: <https://leetcode.cn/u/cctest/>
5354
* 🐶 [weekly contest 290](src/main/java/weekly/wk290.java)
5455
* 🐭 [weekly contest 280](src/main/java/weekly/wk289.java)
5556

57+
* 🐸 [biweekly contest 101](src/main/java/weekly/wkb101.java) 哈希 | 滑动窗口 | 并查集 | BFS
5658
* 🐸 [biweekly contest 100](src/main/java/weekly/wkb100.java) 四维 | 贪心 | 堆 | 二分
5759
* 🐸 [biweekly contest 99](src/main/java/weekly/wkb99.java) 贪心 | 递推 | 区间合并 | 换根DP
5860
* 🐸 [biweekly contest 98](src/main/java/weekly/wkb98.java)

src/main/java/weekly/wk339.java

+202
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
package weekly;
2+
3+
import java.util.ArrayDeque;
4+
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.Comparator;
7+
import java.util.HashSet;
8+
import java.util.LinkedList;
9+
import java.util.List;
10+
import java.util.PriorityQueue;
11+
import java.util.Queue;
12+
import java.util.Set;
13+
import java.util.TreeSet;
14+
15+
public class wk339 {
16+
17+
//模拟
18+
static public int findTheLongestBalancedSubstring(String s) {
19+
int i = 0;
20+
int ans = 0;
21+
while (i < s.length()) {
22+
int zero = 0;
23+
while (i < s.length() && s.charAt(i) == '0') {
24+
zero++;
25+
i++;
26+
}
27+
int one = 0;
28+
while (i < s.length() && s.charAt(i) == '1') {
29+
one++;
30+
i++;
31+
}
32+
ans = Math.max(Math.min(zero, one) * 2, ans);
33+
}
34+
return ans;
35+
}
36+
37+
38+
//hash
39+
public List<List<Integer>> findMatrix(int[] nums) {
40+
Arrays.sort(nums);
41+
42+
int pre = nums[0];
43+
int count = 1;
44+
List<List<Integer>> res = new ArrayList<>();
45+
for (int i = 1; i < nums.length; i++) {
46+
if (nums[i] == pre) {
47+
count++;
48+
} else {
49+
while (res.size() < count) {
50+
res.add(new ArrayList<>());
51+
}
52+
for (int j = 0; j < count; j++) {
53+
res.get(j).add(pre);
54+
}
55+
pre = nums[i];
56+
count = 1;
57+
}
58+
}
59+
while (res.size() < count) {
60+
res.add(new ArrayList<>());
61+
}
62+
for (int j = 0; j < count; j++) {
63+
res.get(j).add(pre);
64+
}
65+
66+
return res;
67+
}
68+
69+
70+
//贪心
71+
static public int miceAndCheese(int[] reward1, int[] reward2, int k) {
72+
73+
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(Comparator.reverseOrder());
74+
75+
int sum = 0;
76+
for (int i = 0; i < reward1.length; i++) {
77+
int dis = reward1[i] - reward2[i];
78+
priorityQueue.add(dis);
79+
sum += reward2[i];
80+
}
81+
82+
while (k > 0) {
83+
sum += priorityQueue.poll();
84+
k--;
85+
}
86+
return sum;
87+
88+
}
89+
90+
91+
//直接遍历超时
92+
/*static public int[] minReverseOperations(int n, int p, int[] banned, int k) {
93+
int[] res = new int[n];
94+
Set<Integer> banSet = new HashSet<>();
95+
for (int i : banned) {
96+
banSet.add(i);
97+
}
98+
//存储未查询的点
99+
Set<Integer> treeSet=new TreeSet<>();
100+
for (int i = 0; i < n; i++) {
101+
treeSet.add(i);
102+
}
103+
Queue<Integer> queue = new LinkedList<>();
104+
queue.add(p);
105+
treeSet.remove(p);
106+
for (int i = 0; i < res.length; i++) {
107+
res[i] = -1;
108+
}
109+
res[p] = 0;
110+
boolean[] visited = new boolean[n];
111+
int step = 0;
112+
while (!queue.isEmpty()) {
113+
step++;
114+
int size = queue.size();
115+
while (size-- > 0) {
116+
int cur = queue.poll();
117+
visited[cur] = true;
118+
119+
int r=cur+k-1;
120+
int l=cur-k+1;
121+
for (int i = k; i > 1; i -= 2) {
122+
//左移
123+
int left = cur - i + 1;
124+
int ll = (l++);
125+
int lr = ll+k-1;
126+
//右移动
127+
int right = cur + i - 1;
128+
int rr=(r--);
129+
int rl=rr-k+1;
130+
131+
if (left >= 0 && lr<n&&ll>=0 && !visited[left] && !banSet.contains(left)) {
132+
visited[left] = true;
133+
queue.add(left);
134+
res[left] = step;
135+
}
136+
137+
if (right < n &&rl>=0&&rr<n && !visited[right] && !banSet.contains(right)) {
138+
visited[right] = true;
139+
queue.add(right);
140+
res[right] = step;
141+
}
142+
}
143+
}
144+
}
145+
return res;
146+
}*/
147+
148+
149+
//广度优先+有序集合
150+
static public int[] minReverseOperations(int n, int p, int[] banned, int k) {
151+
int[] res = new int[n];
152+
Set<Integer> banSet = new HashSet<>();
153+
for (int i : banned) {
154+
banSet.add(i);
155+
}
156+
banSet.add(p);
157+
//存储未查询的点
158+
TreeSet<Integer> treeEven = new TreeSet<>();
159+
TreeSet<Integer> treeOdd = new TreeSet<>();
160+
161+
TreeSet<Integer> sets[] = new TreeSet[2];
162+
sets[0] = treeEven;
163+
sets[1] = treeOdd;
164+
treeEven.add(n);
165+
treeOdd.add(n);
166+
for (int i = 0; i < n; i++) {
167+
if (banSet.contains(i)) continue;
168+
if (i % 2 == 0) {
169+
treeEven.add(i);
170+
} else {
171+
treeOdd.add(i);
172+
}
173+
}
174+
Queue<Integer> queue = new LinkedList<>();
175+
queue.add(p);
176+
for (int i = 0; i < res.length; i++) {
177+
res[i] = -1;
178+
}
179+
int step = 0;
180+
while (!queue.isEmpty()) {
181+
int size = queue.size();
182+
while (size-- > 0) {
183+
Integer i = queue.poll();
184+
res[i] = step;
185+
// 从 mn 到 mx 的所有位置都可以翻转到
186+
int mn = Math.max(i - k + 1, k - i - 1);
187+
int mx = Math.min(i + k - 1, n * 2 - k - i - 1);
188+
TreeSet<Integer> s = sets[mn % 2];
189+
for (int j = s.ceiling(mn); j <= mx; j = s.ceiling(mn)) {
190+
queue.add(j);
191+
s.remove(j);
192+
}
193+
}
194+
step++;
195+
}
196+
return res;
197+
}
198+
199+
public static void main(String[] args) {
200+
minReverseOperations(4, 0, new int[]{1,2}, 4);
201+
}
202+
}

src/main/java/weekly/wkb101.java

+174
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package weekly;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.HashMap;
7+
import java.util.HashSet;
8+
import java.util.LinkedList;
9+
import java.util.List;
10+
import java.util.Map;
11+
import java.util.Queue;
12+
import java.util.Set;
13+
14+
public class wkb101 {
15+
//哈希
16+
public int minNumber(int[] nums1, int[] nums2) {
17+
Arrays.sort(nums1);
18+
Arrays.sort(nums2);
19+
20+
Set<Integer> set = new HashSet<>();
21+
22+
for (int i : nums2) {
23+
set.add(i);
24+
}
25+
26+
for (int i : nums1) {
27+
if (set.contains(i)) return i;
28+
}
29+
30+
return Math.min(nums1[0] * 10 + nums2[0], nums2[0] * 10 + nums1[0]);
31+
}
32+
33+
34+
//滑动窗口
35+
public int maximumCostSubstring(String s, String chars, int[] vals) {
36+
int[] scores = new int[26];
37+
for (int i = 0; i < scores.length; i++) {
38+
scores[i] = i + 1;
39+
}
40+
for (int i = 0; i < chars.length(); i++) {
41+
char c = chars.charAt(i);
42+
scores[c - 'a'] = vals[i];
43+
}
44+
int max = 0;
45+
int sum = 0;
46+
for (int i = 0; i < s.length(); i++) {
47+
char c = s.charAt(i);
48+
sum += scores[c - 'a'];
49+
max = Math.max(sum, max);
50+
if (sum < 0) {
51+
sum = 0;
52+
}
53+
}
54+
return max;
55+
}
56+
57+
//并查集
58+
class UnionFind {
59+
public final int[] parents;
60+
public int count;
61+
62+
public UnionFind(int n) {
63+
this.parents = new int[n];
64+
reset();
65+
}
66+
67+
public void reset() {
68+
for (int i = 0; i < parents.length; i++) {
69+
parents[i] = i;
70+
}
71+
count = parents.length - 1;
72+
}
73+
74+
public int find(int i) {
75+
int parent = parents[i];
76+
if (parent == i) {
77+
return i;
78+
} else {
79+
int root = find(parent);
80+
parents[i] = root;
81+
return root;
82+
}
83+
}
84+
85+
public boolean union(int i, int j) {
86+
int r1 = find(i);
87+
int r2 = find(j);
88+
if (r1 != r2) {
89+
count--;
90+
parents[r1] = r2;
91+
return true;
92+
} else {
93+
return false;
94+
}
95+
}
96+
97+
/* void isolate(int x) {
98+
if (x != parents[x]) {
99+
parents[x] = x;
100+
count++;
101+
}
102+
}*/
103+
104+
}
105+
106+
107+
//并查集分组计算
108+
public long makeSubKSumEqual(int[] arr, int k) {
109+
UnionFind uf = new UnionFind(arr.length);
110+
for (int i = 0; i < arr.length; i++) {
111+
uf.union(i, (i + k) % arr.length);
112+
}
113+
Map<Integer, List<Integer>> map = new HashMap<>();
114+
115+
for (int i = 0; i < arr.length; i++) {
116+
int key = uf.find(i);
117+
if (!map.containsKey(key)) map.put(key, new ArrayList<>());
118+
map.get(key).add(arr[i]);
119+
}
120+
121+
long ans = 0;
122+
for (List<Integer> list : map.values()) {
123+
Collections.sort(list);
124+
int mid = list.get(list.size() / 2);
125+
for (Integer num : list) {
126+
ans += Math.abs(num - mid);
127+
}
128+
}
129+
return ans;
130+
}
131+
132+
133+
//bfs、迪杰斯特拉
134+
public int findShortestCycle(int n, int[][] edges) {
135+
Map<Integer, List<Integer>> map = new HashMap<>();
136+
for (int[] edge : edges) {
137+
if (!map.containsKey(edge[0])) map.put(edge[0], new ArrayList<>());
138+
if (!map.containsKey(edge[1])) map.put(edge[1], new ArrayList<>());
139+
map.get(edge[0]).add(edge[1]);
140+
map.get(edge[1]).add(edge[0]);
141+
}
142+
143+
boolean[] visited = new boolean[n];
144+
for (int i = 0; i < n; i++) {
145+
help(map, i,n);
146+
}
147+
return ans == Integer.MAX_VALUE ? -1 : ans;
148+
}
149+
150+
int ans = Integer.MAX_VALUE;
151+
152+
void help(Map<Integer, List<Integer>> map, int cur, int n) {
153+
int[] dis = new int[n];
154+
Arrays.fill(dis, -1);
155+
dis[cur] = 0;
156+
Queue<int[]> queue = new LinkedList<>();
157+
queue.add(new int[]{cur, -1});
158+
while (!queue.isEmpty()) {
159+
int[] poll = queue.poll();
160+
int x = poll[0];
161+
int pre = poll[1];
162+
for (Integer y : map.getOrDefault(x, new ArrayList<>())) {
163+
//未访问过该点
164+
if (dis[y] < 0) {
165+
dis[y] = dis[x] + 1;
166+
queue.add(new int[]{y, x});
167+
//非第一次访问
168+
} else if(y!=pre) {
169+
ans = Math.min(ans, dis[x] + dis[y] + 1);
170+
}
171+
}
172+
}
173+
}
174+
}

0 commit comments

Comments
 (0)