Skip to content

Commit c9286ae

Browse files
committed
weekly contest 319
1 parent 9d3f8be commit c9286ae

File tree

3 files changed

+354
-0
lines changed

3 files changed

+354
-0
lines changed

README.md

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

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

7+
8+
* ☀️ [weekly contest 319](src/main/java/weekly/wk319.java) 模拟 | 暴力 | 置换环 | DP
79
* ☀️ [weekly contest 318](src/main/java/weekly/wk318.java) 模拟 | 滑动窗口 | 双指针 | DP
810
* ☀️ [weekly contest 317](src/main/java/weekly/wk317.java) 数组 | hash | 贪心+模拟 | 树形DP
911
* ☀️ [weekly contest 316](src/main/java/weekly/wk316.java) 模拟 | gcd | 前缀和 | 分情况
@@ -35,6 +37,8 @@ leetcode url: <https://leetcode.cn/u/cctest/>
3537
* 🐶 [weekly contest 290](src/main/java/weekly/wk290.java)
3638
* 🐭 [weekly contest 280](src/main/java/weekly/wk289.java)
3739

40+
41+
* 🐸 [biweekly contest 91](src/main/java/weekly/wkb91.java) 排序 | DO | DFS | 找规律
3842
* 🐸 [biweekly contest 90](src/main/java/weekly/wkb90.java) hash | 遍历 | 分组求余 | 单调栈+优先队列
3943
* 🐸 [biweekly contest 89](src/main/java/weekly/wkb89.java) 判断 | 前缀和 | 贪心、二分 | 枚举+DFS
4044
* 🐘 [biweekly contest 88](src/main/java/weekly/wkb88.java) 模拟 | 指针 | 脑筋急转弯 | 线段树

src/main/java/weekly/wk319.java

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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.HashMap;
8+
import java.util.HashSet;
9+
import java.util.LinkedList;
10+
import java.util.List;
11+
import java.util.Map;
12+
import java.util.Queue;
13+
import java.util.Set;
14+
15+
public class wk319 {
16+
17+
//ranking: 628 / 6175
18+
19+
//模拟
20+
public double[] convertTemperature(double celsius) {
21+
return new double[]{celsius + 273.15, celsius * 1.80 + 32};
22+
}
23+
24+
25+
//暴力做的
26+
public int subarrayLCM(int[] nums, int k) {
27+
28+
int res = 0;
29+
for (int i = 0; i < nums.length; i++) {
30+
int s = nums[i];
31+
for (int j = i; j < nums.length; j++) {
32+
//两数乘积=两数的最大公因数×两数的最小公倍数
33+
s = (int) (s / gcd(nums[j], s) * nums[j]);
34+
if (s == k) {
35+
res++;
36+
}
37+
if (s > k) break;
38+
}
39+
System.out.println(res);
40+
}
41+
return res;
42+
}
43+
44+
long gcd(long a, long b) {
45+
while (b != 0) {
46+
long temp = a % b;
47+
a = b;
48+
b = temp;
49+
}
50+
return a;
51+
}
52+
53+
// public static int getCM(int m, int n) {
54+
// for (int i = (m > n ? m : n); i <= m * n; i++) {
55+
// if (i % n == 0 && i % m == 0) {
56+
// return i;
57+
// }
58+
// }
59+
// return -1;
60+
// }
61+
62+
public class TreeNode {
63+
int val;
64+
TreeNode left;
65+
TreeNode right;
66+
67+
TreeNode() {
68+
}
69+
70+
TreeNode(int val) {
71+
this.val = val;
72+
}
73+
74+
TreeNode(int val, TreeNode left, TreeNode right) {
75+
this.val = val;
76+
this.left = left;
77+
this.right = right;
78+
}
79+
}
80+
81+
82+
//层序遍历,然后求每层的最小交换此次数,问题转换了-置换环
83+
public int minimumOperations(TreeNode root) {
84+
Queue<TreeNode> queue = new LinkedList<>();
85+
queue.add(root);
86+
int res = 0;
87+
while (!queue.isEmpty()) {
88+
int size = queue.size();
89+
List<Integer> list = new ArrayList<>(size);
90+
while (size-- > 0) {
91+
TreeNode node = queue.poll();
92+
list.add(node.val);
93+
if (node.left != null) queue.add(node.left);
94+
if (node.right != null) queue.add(node.right);
95+
}
96+
int ans = minSwaps(list);
97+
res += ans;
98+
}
99+
return res;
100+
}
101+
102+
public static int minSwaps(List<Integer> list) {
103+
int n = list.size();
104+
105+
ArrayList<int[]> arrpos = new ArrayList<>();
106+
for (int i = 0; i < n; i++)
107+
arrpos.add(new int[]{list.get(i), i});
108+
109+
arrpos.sort(new Comparator<int[]>() {
110+
@Override
111+
public int compare(int[] o1, int[] o2) {
112+
if (o1[0] < o2[0])
113+
return -1;
114+
else if (o1[0] == o2[0])
115+
return 0;
116+
else
117+
return 1;
118+
}
119+
});
120+
boolean[] vis = new boolean[n];
121+
int ans = 0;
122+
for (int i = 0; i < n; i++) {
123+
if (vis[i] || arrpos.get(i)[1] == i)
124+
continue;
125+
int cycle_size = 0;
126+
int j = i;
127+
while (!vis[j]) {
128+
vis[j] = true;
129+
j = arrpos.get(j)[1];
130+
cycle_size++;
131+
}
132+
if (cycle_size > 0) {
133+
ans += (cycle_size - 1);
134+
}
135+
}
136+
return ans;
137+
}
138+
139+
//dp
140+
static public int maxPalindromes(String s, int k) {
141+
int[] dp = new int[s.length() + 1];
142+
boolean[][] can = new boolean[s.length()][s.length()];
143+
for (int i = 0; i < can.length; i++) {
144+
can[i][i] = true;
145+
}
146+
//求所有的回文串,这里也可以中心扩展法
147+
for (int len = 2; len <= s.length(); len++) {
148+
for (int i = 0; i + len <= s.length(); i++) {
149+
if (s.charAt(i) == s.charAt(i + len - 1)) {
150+
if (len == 2) {
151+
can[i][i + len - 1] = true;
152+
} else {
153+
can[i][i + len - 1] |= can[i + 1][i + len - 2];
154+
}
155+
}
156+
}
157+
}
158+
159+
if (can[0][k - 1]) {
160+
dp[k] = 1;
161+
}
162+
163+
//dp[i]表示i结尾的满足长度为k的回文序列的个数
164+
//从k长度开始找
165+
for (int i = k; i < s.length(); i++) {
166+
dp[i + 1] = dp[i];
167+
for (int begin = i - k + 1; begin >= 0; begin--) {
168+
if (can[begin][i]) {
169+
dp[i + 1] = Math.max(dp[i + 1], dp[begin] + 1);
170+
}
171+
}
172+
}
173+
return dp[dp.length - 1];
174+
}
175+
176+
//检查是不是回文串
177+
static boolean check(String s, int begin, int end) {
178+
while (begin < end) {
179+
if (s.charAt(begin) != s.charAt(end)) {
180+
return false;
181+
}
182+
begin++;
183+
end--;
184+
}
185+
return true;
186+
}
187+
188+
public static void main(String[] args) {
189+
maxPalindromes("fttfjofpnpfydwdwdnns", 2);
190+
}
191+
192+
}

src/main/java/weekly/wkb91.java

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package weekly;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.HashMap;
6+
import java.util.HashSet;
7+
import java.util.List;
8+
import java.util.Map;
9+
import java.util.Set;
10+
11+
public class wkb91 {
12+
//ranking: 400 / 3535
13+
//排序+hash
14+
public int distinctAverages(int[] nums) {
15+
Arrays.sort(nums);
16+
Set<Integer> set = new HashSet<>();
17+
for (int i = 0; i < nums.length / 2; i++) {
18+
set.add(nums[i] + nums[nums.length - 1 - i]);
19+
}
20+
return set.size();
21+
}
22+
23+
// dp
24+
public int countGoodStrings(int low, int high, int zero, int one) {
25+
long[] dp = new long[high + 1];
26+
int mod = (int) 1e9 + 7;
27+
dp[0] = 1;
28+
for (int i = 0; i < dp.length; i++) {
29+
if (i - zero > 0) dp[i] += dp[i - zero];
30+
if (i - one > 0) dp[i] += dp[i - one];
31+
dp[i] %= mod;
32+
}
33+
long res = 0;
34+
for (int i = low; i <= high; i++) {
35+
res += dp[i];
36+
res %= mod;
37+
}
38+
return (int) res;
39+
}
40+
41+
42+
//两次dfs
43+
public int mostProfitablePath(int[][] edges, int bob, int[] amount) {
44+
Map<Integer, List<Integer>> map = new HashMap<>();
45+
for (int[] edge : edges) {
46+
if (!map.containsKey(edge[0])) map.put(edge[0], new ArrayList<>());
47+
if (!map.containsKey(edge[1])) map.put(edge[1], new ArrayList<>());
48+
map.get(edge[0]).add(edge[1]);
49+
map.get(edge[1]).add(edge[0]);
50+
}
51+
arrivedTime = new HashMap<>();
52+
helpBob(0, -1, bob, 0, map);
53+
54+
return helpAlice(0, -1, 0, map, amount);
55+
}
56+
57+
int bobStep;
58+
Map<Integer, Integer> arrivedTime;
59+
60+
//bob的路线是固定的,计算bob打到每个节点的步数
61+
boolean helpBob(int cur, int pre, int bob, int step, Map<Integer, List<Integer>> map) {
62+
if (cur == bob) {
63+
arrivedTime.put(cur, step);
64+
bobStep = step;
65+
return true;
66+
}
67+
68+
boolean flag = false;
69+
for (Integer next : map.getOrDefault(cur, new ArrayList<>())) {
70+
if (next == pre) continue;
71+
flag |= helpBob(next, cur, bob, step + 1, map);
72+
}
73+
if (flag) {
74+
arrivedTime.put(cur, step);
75+
}
76+
return flag;
77+
}
78+
79+
//求alice达到每个叶子结点的分数,求最大
80+
int helpAlice(int cur, int pre, int step, Map<Integer, List<Integer>> map, int[] amount) {
81+
int score = 0;
82+
if (arrivedTime.containsKey(cur)) {
83+
int time = bobStep - arrivedTime.get(cur);
84+
//比bob先打到
85+
if (time > step) {
86+
score += amount[cur];
87+
//一起到达
88+
} else if (time == step) {
89+
score += amount[cur] / 2;
90+
}
91+
//bob没有经过
92+
} else {
93+
score += amount[cur];
94+
}
95+
96+
int max = Integer.MIN_VALUE;
97+
for (Integer next : map.getOrDefault(cur, new ArrayList<>())) {
98+
if (next == pre) continue;
99+
max = Math.max(max, helpAlice(next, cur, step + 1, map, amount));
100+
}
101+
//这里表示没有路了
102+
if (max == Integer.MIN_VALUE) {
103+
max = 0;
104+
}
105+
return score + max;
106+
}
107+
108+
109+
//写的好麻烦,本质是找规律
110+
public String[] splitMessage(String message, int limit) {
111+
int length = message.length();
112+
int number = check(length, limit);
113+
if (number == -1) {
114+
return new String[]{};
115+
}
116+
int l = (number + "").length();
117+
String[] res = new String[number];
118+
int begin = 0;
119+
for (int i = 1; i <= number; i++) {
120+
int r = (i + "").length();
121+
int end = begin + (limit - 3 - r - l);
122+
res[i - 1] = message.substring(begin, Math.min(message.length(), end)) + "<" + i + "/" + number + ">";
123+
begin = end;
124+
}
125+
return res;
126+
}
127+
128+
//计算要分成多少组
129+
int check(int len, int limit) {
130+
for (int i = 1; i < arr.length + 1; i++) {
131+
long sum = 0;
132+
for (int j = 0; j < i; j++) {
133+
sum += (long) arr[j] * (limit - i - j - 1 - 3);
134+
}
135+
if (sum >= len) {
136+
int count=0;
137+
for (int j = 0; j < i - 1; j++) {
138+
count+=arr[j];
139+
len -= arr[j] * (limit - i - j - 1 - 3);
140+
}
141+
int l = len / (limit - i - i - 3);
142+
if (l * (limit - i - i - 3) != len) {
143+
l++;
144+
}
145+
return count + l;
146+
}
147+
}
148+
return -1;
149+
}
150+
151+
int[] arr = new int[]{9, 90, 900, 9000, 90000, 900000};
152+
153+
// public static void main(String[] args) {
154+
// wk319 w = new wk319();
155+
// w.check(10000, 12);
156+
// w.splitMessage("this is really a very awesome message", 9);
157+
// }
158+
}

0 commit comments

Comments
 (0)