Skip to content

Commit 39faee8

Browse files
committed
weekly contest 346
1 parent 8295aca commit 39faee8

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Record leetcode contest and ideas every week, and encourage yourself to think mo
44

55
leetcode url: <https://leetcode.cn/u/cctest/>
66

7+
* ☀️ [weekly contest 346](src/main/java/weekly/wk346.java) 栈 | 遍历 | 回溯 | Dijkstra
78
* ☀️ [weekly contest 345](src/main/java/weekly/wk345.java) 模拟 | 异或 | dp | 并查集
89
* ☀️ [weekly contest 344](src/main/java/weekly/wk344.java) 前缀和 | 哈希 | 模拟 | 树形dp
910
* ☀️ [weekly contest 343](src/main/java/weekly/wk343.java) 模拟 | 模拟 | Dijkstra

src/main/java/weekly/wk346.java

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
package weekly;
2+
3+
import java.util.ArrayDeque;
4+
import java.util.ArrayList;
5+
import java.util.Arrays;
6+
import java.util.Deque;
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
public class wk346 {
11+
12+
//栈
13+
public int minLength(String s) {
14+
Deque<Character> deque = new ArrayDeque<>();
15+
for (int i = 0; i < s.length(); i++) {
16+
char c = s.charAt(i);
17+
if (deque.size() > 0 && check(c, deque.peekLast())) {
18+
deque.pollLast();
19+
} else {
20+
deque.addLast(c);
21+
}
22+
}
23+
return deque.size();
24+
}
25+
26+
boolean check(char cur, char pre) {
27+
if (cur == 'B' && pre == 'A') {
28+
return true;
29+
}
30+
if (cur == 'D' && pre == 'C') {
31+
return true;
32+
}
33+
return false;
34+
}
35+
36+
//遍历
37+
public String makeSmallestPalindrome(String s) {
38+
char[] chars = s.toCharArray();
39+
int n = s.length();
40+
for (int i = 0; i < s.length(); i++) {
41+
if (chars[i] == chars[n - i - 1]) continue;
42+
char need = ' ';
43+
if (chars[i] - chars[n - i - 1] > 0) {
44+
need = chars[n - i - 1];
45+
} else {
46+
need = chars[i];
47+
}
48+
chars[i] = need;
49+
chars[n - i - 1] = need;
50+
}
51+
return new String(chars);
52+
}
53+
54+
//预处理+回溯
55+
public int punishmentNumber(int n) {
56+
int ans=0;
57+
for (int i = 0; i < list.size(); i++) {
58+
Integer cur = list.get(i);
59+
if(cur <=n){
60+
ans+=cur*cur;
61+
}else {
62+
break;
63+
}
64+
}
65+
return ans;
66+
}
67+
68+
static List<Integer> list = new ArrayList<>();
69+
70+
static {
71+
for (int i = 1; i <= 1000; i++) {
72+
int mul = i * i;
73+
if (check(0, mul + "", 0, i)) {
74+
list.add(i);
75+
}
76+
}
77+
}
78+
79+
static boolean check(int cur, String s, int sum, int target) {
80+
if (cur >= s.length()) {
81+
if (sum == target) return true;
82+
return false;
83+
}
84+
for (int i = cur; i < s.length(); i++) {
85+
String num = s.substring(cur, i + 1);
86+
if (check(i + 1, s, sum + Integer.parseInt(num), target)) {
87+
return true;
88+
}
89+
}
90+
return false;
91+
}
92+
93+
public int[][] modifiedGraphEdges(int n, int[][] edges, int source, int destination, int target) {
94+
List<int[]> g[] = new ArrayList[n];
95+
Arrays.setAll(g, e -> new ArrayList<>());
96+
for (int i = 0; i < edges.length; i++) {
97+
int x = edges[i][0], y = edges[i][1];
98+
g[x].add(new int[]{y, i});
99+
g[y].add(new int[]{x, i}); // 建图,额外记录边的编号
100+
}
101+
102+
int[][] dis = new int[n][2];
103+
for (int i = 0; i < n; i++)
104+
if (i != source)
105+
dis[i][0] = dis[i][1] = Integer.MAX_VALUE;
106+
//第一次遍历 考虑把-1变成1
107+
dijkstra(g, edges, destination, dis, 0, 0);
108+
//1是最小的了,若还比target大只能返回false
109+
int delta = target - dis[destination][0];
110+
if (delta < 0) // -1 全改为 1 时,最短路比 target 还大
111+
return new int[][]{};
112+
113+
//第二次遍历
114+
dijkstra(g, edges, destination, dis, delta, 1);
115+
if (dis[destination][1] < target) // 最短路无法再变大,无法达到 target
116+
return new int[][]{};
117+
118+
for (int[] e : edges)
119+
if (e[2] == -1) // 剩余没修改的边全部改成 1
120+
e[2] = 1;
121+
return edges;
122+
}
123+
124+
// 朴素 Dijkstra 算法
125+
// 这里 k 表示第一次/第二次
126+
private void dijkstra(List<int[]> g[], int[][] edges, int destination, int[][] dis, int delta, int k) {
127+
int n = g.length;
128+
boolean[] vis = new boolean[n];
129+
for (; ; ) {
130+
// 找到当前最短路,去更新它的邻居的最短路
131+
// 根据数学归纳法,dis[x][k] 一定是最短路长度
132+
int x = -1;
133+
//找最短路径x且没被访问过x
134+
for (int i = 0; i < n; ++i)
135+
if (!vis[i] && (x < 0 || dis[i][k] < dis[x][k]))
136+
x = i;
137+
if (x == destination) // 起点 source 到终点 destination 的最短路已确定
138+
return;
139+
vis[x] = true; // 标记,在后续的循环中无需反复更新 x 到其余点的最短路长度
140+
for (int[] e : g[x]) {
141+
int y = e[0], eid = e[1];
142+
int wt = edges[eid][2];
143+
if (wt == -1)
144+
wt = 1; // -1 改成 1
145+
if (k == 1 && edges[eid][2] == -1) {
146+
// 第二次 Dijkstra,改成 w
147+
148+
// x是当前点 y是next
149+
//delta是剩下的距离, dis[y][0]是第一次遍历 start到y的距离
150+
//dis[x][1]是第二次遍历 start到x的距离
151+
// 第二次到x的距离 + x到y的距离 + 第一次到des的距离-第一次到y的距离=target
152+
//求x到y的距离
153+
int w = delta + dis[y][0] - dis[x][1];
154+
if (w > wt)
155+
edges[eid][2] = wt = w; // 直接在 edges 上修改
156+
}
157+
// 更新最短路
158+
dis[y][k] = Math.min(dis[y][k], dis[x][k] + wt);
159+
}
160+
}
161+
}
162+
163+
164+
public static void main(String[] args) {
165+
166+
}
167+
}

0 commit comments

Comments
 (0)