Skip to content

Commit 693b80c

Browse files
committed
weekly contest 309
1 parent f090ff3 commit 693b80c

File tree

3 files changed

+312
-19
lines changed

3 files changed

+312
-19
lines changed

README.md

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,42 @@
1+
# Leetcode weekly
12

2-
# Leetcode weekly
3-
Record leetcode contest and ideas every week, and encourage yourself to think more.
3+
Record leetcode contest and ideas every week, and encourage yourself to think more.
44

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

7-
8-
* 🐷 [weekly contest 308](src/main/java/weekly/wk308.java) 排序+前缀和 | 栈 | 贪心 | 拓扑排序
9-
* 🐻 [weekly contest 307](src/main/java/weekly/wk307.java) 贪心 | 贪心 | 图 | 堆
7+
* 🐼 [weekly contest 309](src/main/java/weekly/wk309.java) 数组 | DP/记忆化搜索 | 滑动窗口 | 双堆
8+
* 🐷 [weekly contest 308](src/main/java/weekly/wk308.java) 排序+前缀和 | 栈 | 贪心 | 拓扑排序
9+
* 🐻 [weekly contest 307](src/main/java/weekly/wk307.java) 贪心 | 贪心 | 图 | 堆
1010
* 🐻 [weekly contest 306](src/main/java/weekly/wk306.java) 数组 | 有向图图 | 贪心、栈 | 数位DP
1111
* 🐨 [weekly contest 305](src/main/java/weekly/wk305.java) Array | Array | DP | DP
1212
* 🐍 [weekly contest 304](src/main/java/weekly/wk304.java) Array | Array Greedy | Graph | Graph Topological Sort
1313
* ☁️ [weekly contest 303](src/main/java/weekly/wk303.java) Array | Simulation | Heap (Priority Queue)|Binary Search
14-
* ☀️ [weekly contest 302](src/main/java/weekly/wk302.java) Array | Heap | Heap| Math GCD
15-
* ☀️ [weekly contest 301](src/main/java/weekly/wk301.java) Greegy | Hash Table | Two Pointers|Dynamic Programming+Combinatorics
14+
* ☀️ [weekly contest 302](src/main/java/weekly/wk302.java) Array | Heap | Heap| Math GCD
15+
* ☀️ [weekly contest 301](src/main/java/weekly/wk301.java) Greegy | Hash Table | Two Pointers|Dynamic
16+
Programming+Combinatorics
1617
* ☀️ [weekly contest 300](src/main/java/weekly/wk300.java) Hash Table | Simulation | DP | DP
17-
*[weekly contest 299](src/main/java/weekly/wk299.java) Array | DP | DP | Enumeration + classification discussion
18-
* ☁️ [weekly contest 298](src/main/java/weekly/wk298.java)
18+
*[weekly contest 299](src/main/java/weekly/wk299.java) Array | DP | DP | Enumeration + classification discussion
19+
* ☁️ [weekly contest 298](src/main/java/weekly/wk298.java)
1920
* ❄️ [weekly contest 297](src/main/java/weekly/wk297.java)
20-
*[weekly contest 296](src/main/java/weekly/wk296.java)
21-
*[weekly contest 295](src/main/java/weekly/wk295.java)
22-
* 🌀 [weekly contest 294](src/main/java/weekly/wk294.java)
21+
*[weekly contest 296](src/main/java/weekly/wk296.java)
22+
*[weekly contest 295](src/main/java/weekly/wk295.java)
23+
* 🌀 [weekly contest 294](src/main/java/weekly/wk294.java)
2324
* 🌁 [weekly contest 293](src/main/java/weekly/wk293.java)
2425
* 🌊 [weekly contest 292](src/main/java/weekly/wk292.java)
25-
* 🐱 [weekly contest 291](src/main/java/weekly/wk291.java)
26-
* 🐶 [weekly contest 290](src/main/java/weekly/wk290.java)
27-
* 🐭 [weekly contest 280](src/main/java/weekly/wk289.java)
26+
* 🐱 [weekly contest 291](src/main/java/weekly/wk291.java)
27+
* 🐶 [weekly contest 290](src/main/java/weekly/wk290.java)
28+
* 🐭 [weekly contest 280](src/main/java/weekly/wk289.java)
2829

30+
* 🐘 [biweekly contest 86](src/main/java/weekly/wkb86.java) 数组 | 脑筋急转弯 | 位运算 | 滑动窗口+单调队列
2931
* 🐹 [biweekly contest 85](src/main/java/weekly/wkb85.java) 滑动窗口 | 模拟 | 差分数组 | 并查集
3032
* 🐹 [biweekly contest 82](src/main/java/weekly/wkb82.java) DFS | Greedy | Greedy| Monotonic Stack/Union Find
31-
* 🐹 [biweekly contest 81](src/main/java/weekly/wkb81.java)
33+
* 🐹 [biweekly contest 81](src/main/java/weekly/wkb81.java)
3234
* 🐰 [biweekly contest 80](src/main/java/weekly/wkb80.java)
3335
* 🐺 [biweekly contest 79](src/main/java/weekly/wkb79.java)
3436
* 🐸 [biweekly contest 78](src/main/java/weekly/wkb78.java)
3537
* 🐯 [biweekly contest 77](src/main/java/weekly/wkb77.java)
3638

37-
38-
39-
🐽 🐮 🐗 🐵 🐒 🐴 🐎 🐫 🐑 🐘 🐼
39+
🐽 🐮 🐗 🐵 🐒 🐴 🐎 🐫 🐑
4040

4141

4242

src/main/java/weekly/wk309.java

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package weekly;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Comparator;
6+
import java.util.HashMap;
7+
import java.util.HashSet;
8+
import java.util.List;
9+
import java.util.Map;
10+
import java.util.PriorityQueue;
11+
import java.util.Set;
12+
import java.util.TreeMap;
13+
14+
public class wk309 {
15+
16+
17+
//ranking: 357 / 7972
18+
19+
//简单题,数组记录字母的位置
20+
public boolean checkDistances(String s, int[] distance) {
21+
int[] count = new int[26];
22+
Arrays.fill(count, -1);
23+
for (int i = 0; i < s.length(); i++) {
24+
char c = s.charAt(i);
25+
if (count[c - 'a'] == -1) {
26+
count[c - 'a'] = i;
27+
} else {
28+
count[c - 'a'] = i - count[c - 'a'] - 1;
29+
}
30+
}
31+
for (int i = 0; i < distance.length; i++) {
32+
if (count[i] == -1) continue;
33+
if (count[i] != distance[i]) return false;
34+
}
35+
return true;
36+
}
37+
38+
39+
//中等题,dp,模拟k次移动,时间复杂度 k*3000,也可以记忆化搜索
40+
public int numberOfWays(int startPos, int endPos, int k) {
41+
int mod = (int) 1e9 + 7;
42+
int MAX = 3002;
43+
long[] dp = new long[MAX];
44+
dp[startPos + 1000] = 1;
45+
for (int i = 0; i < k; i++) {
46+
long[] ndp = new long[MAX];
47+
for (int j = 0; j < MAX; j++) {
48+
int left = j - 1;
49+
int right = j + 1;
50+
if (left >= 0) ndp[j] += dp[left];
51+
ndp[j] %= mod;
52+
if (right < MAX) ndp[j] += dp[right];
53+
ndp[j] %= mod;
54+
}
55+
dp = ndp;
56+
}
57+
58+
return (int) (dp[endPos + 1000] % mod);
59+
60+
}
61+
62+
63+
//中等题,滑动窗口
64+
/* static public int longestNiceSubarray(int[] nums) {
65+
66+
int left = 0;
67+
int ans = 1;
68+
for (int i = 0; i < nums.length; i++) {
69+
for (int j = i - 1; j >= left; j--) {
70+
if ((nums[j] & nums[i]) != 0) {
71+
left = j + 1;
72+
break;
73+
}
74+
}
75+
ans = Math.max(i - left + 1, ans);
76+
// System.out.println(ans);
77+
}
78+
return ans;
79+
}*/
80+
81+
//优雅的滑动窗口,没有bit位重复
82+
static public int longestNiceSubarray(int[] nums) {
83+
int left = 0;
84+
int or = 0;
85+
int ans = 1;
86+
for (int i = 0; i < nums.length; i++) {
87+
while ((or & nums[i]) > 0) {
88+
or ^= nums[left++];//去掉nums[left]的bit位
89+
}
90+
ans = Math.max(i - left + 1, ans);
91+
or |= nums[i];//记录nums[i]的bit位
92+
}
93+
return ans;
94+
}
95+
96+
97+
//困难题,两个堆:一个记录没被占用的会议室,一个记录在开会的会议室
98+
static public int mostBooked(int n, int[][] meetings) {
99+
//先排序
100+
Arrays.sort(meetings, (a, b) -> a[0] - b[0]);
101+
//记录每个会议室的使用次数
102+
int[] count = new int[n];
103+
//记录{开始时间,房间号},每次弹出开始时间最小,房间号最小的会议室
104+
PriorityQueue<int[]> inuse = new PriorityQueue<>((a, b) -> a[0] != b[0] ? a[0] - b[0] : a[1] - b[1]);
105+
PriorityQueue<Integer> notUse = new PriorityQueue<>();
106+
//一开始全部没有使用
107+
for (int i = 0; i < n; i++) {
108+
notUse.add(i);
109+
}
110+
for (int[] meeting : meetings) {
111+
//腾出会议室
112+
while (!inuse.isEmpty() && inuse.peek()[0] <= meeting[0]) {
113+
int[] poll = inuse.poll();
114+
notUse.add(poll[1]);
115+
}
116+
//有空闲会议室,找出最小的
117+
if (!notUse.isEmpty()) {
118+
Integer room = notUse.poll();
119+
count[room]++;
120+
inuse.add(new int[]{meeting[1], room});
121+
//无空闲会议室,找出最先结束的
122+
} else {
123+
int[] room = inuse.poll();
124+
inuse.add(new int[]{room[0] + meeting[1] - meeting[0], room[1]});
125+
count[room[1]]++;
126+
}
127+
}
128+
int max = 0;
129+
int ans = 0;
130+
for (int i = 0; i < count.length; i++) {
131+
//System.out.println(count[i]);
132+
if (count[i] > max) {
133+
max = count[i];
134+
ans = i;
135+
}
136+
}
137+
return ans;
138+
}
139+
140+
141+
public static void main(String[] args) {
142+
mostBooked(3, new int[][]{
143+
{0, 10}, {1, 9}, {2, 8}, {3, 7}, {4, 6}
144+
});
145+
}
146+
147+
148+
}

src/main/java/weekly/wkb86.java

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package weekly;
2+
3+
import java.util.ArrayDeque;
4+
import java.util.Deque;
5+
import java.util.HashSet;
6+
import java.util.Set;
7+
import java.util.TreeMap;
8+
9+
public class wkb86 {
10+
//简单题, set记录数组和
11+
public boolean findSubarrays(int[] nums) {
12+
Set<Integer> set = new HashSet<>();
13+
int sum = nums[0];
14+
for (int i = 1; i < nums.length; i++) {
15+
sum += nums[i];
16+
if (set.contains(sum)) return true;
17+
set.add(sum);
18+
sum -= nums[i - 1];
19+
}
20+
return false;
21+
}
22+
23+
//中等题,进制转换+回文检测
24+
//可以直接返回false,n>=5时,n的(n-2)进制是12,不是回文
25+
public boolean isStrictlyPalindromic(int n) {
26+
for (int i = 2; i < n; i++) {
27+
if (!help(n, i)) return false;
28+
}
29+
return true;
30+
}
31+
32+
boolean help(int n, int k) {
33+
StringBuilder sb = new StringBuilder();
34+
while (n >= k) {
35+
sb.append(n % k);
36+
n /= k;
37+
}
38+
if (n > 0) sb.append(n);
39+
for (int i = 0; i < sb.length() / 2; i++) {
40+
if (sb.charAt(i) != sb.charAt(sb.length() - i - 1)) return false;
41+
}
42+
return true;
43+
}
44+
45+
46+
//中等题,枚举子序列
47+
static public int maximumRows(int[][] mat, int cols) {
48+
49+
//记录每一行的二进制表示
50+
int[] dp = new int[mat.length];
51+
for (int i = 0; i < mat.length; i++) {
52+
int k = 0;
53+
for (int j = 0; j < mat[i].length; j++) {
54+
k = (k << 1) + mat[i][j];
55+
}
56+
dp[i] = k;
57+
//System.out.println(Integer.toBinaryString(k));
58+
}
59+
60+
//子序列枚举,没必要子序列,可以直接遍历
61+
int state = (1 << mat[0].length) - 1;
62+
int max = 0;
63+
for (int i = state; i > 0; i = (i - 1) & state) {
64+
if (Integer.bitCount(i) != cols) continue;
65+
int count = 0;
66+
//求是不是被覆盖的
67+
for (int j = 0; j < dp.length; j++) {
68+
if ((dp[j] | i) == i) count++;
69+
}
70+
// System.out.println(Integer.toBinaryString(i) + " " + count);
71+
max = Math.max(max, count);
72+
}
73+
return max;
74+
}
75+
76+
77+
//困难题,注意题目是连续,所以可以滑动窗口+treemap记录最大的chargeTime
78+
/* public int maximumRobots(int[] chargeTimes, int[] runningCosts, long budget) {
79+
int left = 0;
80+
long sumRunning = 0;
81+
int k = 0;
82+
TreeMap<Integer, Integer> counter = new TreeMap<>();
83+
int ans = 0;
84+
for (int i = 0; i < chargeTimes.length; i++) {
85+
sumRunning += runningCosts[i];
86+
k++;
87+
counter.put(chargeTimes[i], counter.getOrDefault(chargeTimes[i], 0) + 1);
88+
89+
long c = counter.lastKey() + k * sumRunning;
90+
while (left <= i && c > budget) {
91+
Integer le = counter.get(chargeTimes[left]) - 1;
92+
if (le == 0) {
93+
counter.remove(chargeTimes[left]);
94+
} else {
95+
counter.put(chargeTimes[left], le);
96+
}
97+
sumRunning-=runningCosts[left];
98+
left++;
99+
k--;
100+
if (counter.size() == 0) {
101+
break;
102+
}
103+
c = counter.lastKey() + k * sumRunning;
104+
}
105+
ans = Math.max(ans, k);
106+
}
107+
return ans;
108+
}*/
109+
110+
//单调队列写法
111+
static public int maximumRobots(int[] chargeTimes, int[] runningCosts, long budget) {
112+
int left = 0;
113+
long sumRunning = 0;
114+
Deque<Integer> deque = new ArrayDeque<>();
115+
int ans = 0;
116+
for (int i = 0; i < chargeTimes.length; i++) {
117+
sumRunning += runningCosts[i];
118+
while (!deque.isEmpty() && chargeTimes[deque.peekLast()] <= chargeTimes[i]) {
119+
deque.pollLast();
120+
}
121+
deque.addLast(i);
122+
123+
long c = chargeTimes[deque.peekFirst()] + (i-left+1) * sumRunning;
124+
while (left <= i && c > budget) {
125+
126+
sumRunning -= runningCosts[left];
127+
left++;
128+
while (!deque.isEmpty() && deque.peekFirst() < left) {
129+
deque.pollFirst();
130+
}
131+
if (deque.isEmpty()) {
132+
break;
133+
}
134+
135+
c = chargeTimes[deque.peekFirst()] + (i-left+1) * sumRunning;
136+
}
137+
ans = Math.max(ans, (i-left+1));
138+
}
139+
return ans;
140+
}
141+
142+
public static void main(String[] args) {
143+
maximumRobots(new int[]{11,12,19},new int[]{10,8,7},19);
144+
}
145+
}

0 commit comments

Comments
 (0)