Skip to content

Commit ef605f3

Browse files
committed
683-1088-1153-1183-1199 (5)
1 parent 77f926c commit ef605f3

File tree

12 files changed

+382
-0
lines changed

12 files changed

+382
-0
lines changed

atcoder-beginner/src/main/java/c279/Abc279_d.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,6 @@ private static double f(long A, long B, long k) {
3838
https://atcoder.jp/contests/abc279/tasks/abc279_d
3939
4040
凹函数,三分法取最小值。
41+
https://atcoder.jp/contests/abc279/submissions/37250161
42+
mumuxinfei: java的精度 没法过, 就这样,太sb了
4143
*/

leetcode-05/src/main/java/Solution411.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ private String abbreviation(int mask) {
122122
target 和 dictionary[i] 仅包含小写字符
123123
124124
位运算 + 剪枝
125+
java continue label 参考 https://leetcode.cn/problems/minimum-unique-word-abbreviation/solution/yu-niang-niang-411-zui-duan-du-zhan-dan-9ssj0/
125126
相似题目: $320. 列举单词的全部缩写
126127
https://leetcode.cn/problems/generalized-abbreviation/
127128
$408. 有效单词缩写
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
public class Solution683 {
2+
private int ans;
3+
private int left;
4+
private int right;
5+
6+
public int kEmptySlots(int[] bulbs, int k) {
7+
int n = bulbs.length;
8+
int[] days = new int[n];
9+
for (int i = 0; i < n; i++) {
10+
days[bulbs[i] - 1] = i + 1;
11+
}
12+
13+
ans = Integer.MAX_VALUE;
14+
left = 0;
15+
right = k + 1;
16+
extracted(k, n, days);
17+
return ans == Integer.MAX_VALUE ? -1 : ans;
18+
}
19+
20+
private void extracted(int k, int n, int[] days) {
21+
while (right < n) {
22+
for (int i = left + 1; i < right; i++) {
23+
if (days[i] < days[left] || days[i] < days[right]) {
24+
left = i;
25+
right = i + k + 1;
26+
extracted(k, n, days);
27+
return;
28+
}
29+
}
30+
ans = Math.min(ans, Math.max(days[left], days[right]));
31+
left = right;
32+
right = left + k + 1;
33+
}
34+
}
35+
36+
public int kEmptySlots2(int[] bulbs, int k) {
37+
int[] days = new int[bulbs.length];
38+
for (int i = 0; i < bulbs.length; i++) {
39+
days[bulbs[i] - 1] = i + 1;
40+
}
41+
42+
int ans = Integer.MAX_VALUE;
43+
int left = 0, right = k + 1;
44+
45+
// search:
46+
while (right < days.length) {
47+
boolean flag = false;
48+
for (int i = left + 1; i < right; ++i) {
49+
if (days[i] < days[left] || days[i] < days[right]) {
50+
left = i;
51+
right = i + k + 1;
52+
flag = true;
53+
break;
54+
// continue search;
55+
}
56+
}
57+
if (flag) {
58+
continue;
59+
}
60+
61+
ans = Math.min(ans, Math.max(days[left], days[right]));
62+
left = right;
63+
right = left + k + 1;
64+
}
65+
66+
return ans < Integer.MAX_VALUE ? ans : -1;
67+
}
68+
}
69+
/*
70+
$683. K 个关闭的灯泡
71+
https://leetcode.cn/problems/k-empty-slots/
72+
73+
n 个灯泡排成一行,编号从 1 到 n 。最初,所有灯泡都关闭。每天 只打开一个 灯泡,直到 n 天后所有灯泡都打开。
74+
给你一个长度为 n 的灯泡数组 blubs ,其中 bulls[i] = x 意味着在第 (i+1) 天,我们会把在位置 x 的灯泡打开,其中 i 从 0 开始,x 从 1 开始。
75+
给你一个整数 k ,请返回恰好有两个打开的灯泡,且它们中间 正好 有 k 个 全部关闭的 灯泡的 最小的天数 。如果不存在这种情况,返回 -1 。
76+
提示:
77+
n == bulbs.length
78+
1 <= n <= 2 * 10^4
79+
1 <= bulbs[i] <= n
80+
bulbs 是一个由从 1 到 n 的数字构成的排列
81+
0 <= k <= 2 * 10^4
82+
83+
滑动窗口
84+
java continue label 参考 https://leetcode.cn/problems/k-empty-slots/solution/k-ge-kong-hua-pen-by-leetcode/
85+
*/
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution683Tests {
5+
private final Solution683 solution683 = new Solution683();
6+
7+
@Test
8+
public void example1() {
9+
int[] bulbs = {1, 3, 2};
10+
int k = 1;
11+
int expected = 2;
12+
Assertions.assertEquals(expected, solution683.kEmptySlots(bulbs, k));
13+
Assertions.assertEquals(expected, solution683.kEmptySlots2(bulbs, k));
14+
}
15+
16+
@Test
17+
public void example2() {
18+
int[] bulbs = {1, 2, 3};
19+
int k = 1;
20+
int expected = -1;
21+
Assertions.assertEquals(expected, solution683.kEmptySlots(bulbs, k));
22+
Assertions.assertEquals(expected, solution683.kEmptySlots2(bulbs, k));
23+
}
24+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
public class Solution1088 {
2+
private static final int[] NUM = {0, 1, 6, 8, 9};
3+
private static final int[] REV = {0, 1, 9, 8, 6};
4+
private int n;
5+
private int res;
6+
7+
public int confusingNumberII(int n) {
8+
this.n = n;
9+
res = 0;
10+
dfs(0, 0, 0);
11+
return res;
12+
}
13+
14+
private void dfs(int cur, int rev, int digit) {
15+
if (cur > n) {
16+
return;
17+
}
18+
if (cur != rev) {
19+
res++;
20+
}
21+
22+
for (int i = 0; i < 5; i++) {
23+
if (digit == 0 && i == 0) {
24+
// 前导零不符合要求
25+
continue;
26+
}
27+
if (cur > n / 10) {
28+
// 剪枝 重要!
29+
return;
30+
}
31+
int nextCur = cur * 10 + NUM[i];
32+
int nextRev = REV[i] * (int) Math.pow(10, digit) + rev;
33+
dfs(nextCur, nextRev, digit + 1);
34+
}
35+
}
36+
}
37+
/*
38+
$1088. 易混淆数 II
39+
https://leetcode.cn/problems/confusing-number-ii/
40+
41+
易混淆数(Confusing Number)指的是一个数字在整体旋转 180° 以后,能够得到一个和原来 不同 的数,且 新数字的每一位都应该是有效的。
42+
本题我们会将数字旋转 180° 来生成一个新的数字。
43+
- 当 0、1、6、8、9 旋转 180° 以后,我们得到的新数字分别为 0、1、9、8、6。
44+
- 当 2、3、4、5、7 旋转 180° 后,是 无法 得到任何数字的。
45+
请注意,在旋转一个数字之后,我们可以忽略前导零。
46+
- 例如,在旋转 8000 之后,我们有 0008 ,它被认为只是 8 。
47+
给出正整数 n,请你返回 [1, n] 范围内的 易混淆数 的数量 。
48+
提示:
49+
1 <= n <= 10^9
50+
51+
DFS
52+
相似题目: $1056. 易混淆数
53+
https://leetcode.cn/problems/confusing-number/
54+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution1088Tests {
5+
private final Solution1088 solution1088 = new Solution1088();
6+
7+
@Test
8+
public void example1() {
9+
int n = 20;
10+
int expected = 6;
11+
Assertions.assertEquals(expected, solution1088.confusingNumberII(n));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int n = 100;
17+
int expected = 19;
18+
Assertions.assertEquals(expected, solution1088.confusingNumberII(n));
19+
}
20+
21+
// 补充用例
22+
@Test
23+
public void example3() {
24+
// https://leetcode.cn/submissions/detail/396708705/
25+
// java.lang.StackOverflowError
26+
int n = 1000000000;
27+
int expected = 1950627;
28+
Assertions.assertEquals(expected, solution1088.confusingNumberII(n));
29+
}
30+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import java.util.HashMap;
2+
import java.util.HashSet;
3+
import java.util.Map;
4+
import java.util.Set;
5+
6+
public class Solution1153 {
7+
public boolean canConvert(String str1, String str2) {
8+
if (str1.equals(str2)) {
9+
return true;
10+
}
11+
Map<Character, Character> map = new HashMap<>();
12+
Set<Character> set = new HashSet<>();
13+
for (int i = 0; i < str1.length(); i++) {
14+
if (!map.containsKey(str1.charAt(i))) {
15+
map.put(str1.charAt(i), str2.charAt(i));
16+
set.add(str2.charAt(i));
17+
} else if (map.get(str1.charAt(i)) != str2.charAt(i)) {
18+
return false;
19+
}
20+
}
21+
return set.size() < 26;
22+
}
23+
}
24+
/*
25+
$1153. 字符串转化
26+
https://leetcode.cn/problems/string-transforms-into-another-string/
27+
28+
给出两个长度相同的字符串 str1 和 str2。请你帮忙判断字符串 str1 能不能在 零次 或 多次 转化 后变成字符串 str2。
29+
每一次转化时,你可以将 str1 中出现的 所有 相同字母变成其他 任何 小写英文字母。
30+
只有在字符串 str1 能够通过上述方式顺利转化为字符串 str2 时才能返回 true 。
31+
提示:
32+
1 <= str1.length == str2.length <= 10^4
33+
str1 和 str2 中都只会出现小写英文字母
34+
35+
当 str1 中某两个下标 i 和 j 字符相同时,那么 str2 中这个两个下标的字符也必须相同
36+
*/
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import java.util.ArrayList;
2+
import java.util.Comparator;
3+
import java.util.List;
4+
5+
public class Solution1183 {
6+
public int maximumNumberOfOnes(int width, int height, int sideLength, int maxOnes) {
7+
List<Integer> nodes = new ArrayList<>();
8+
for (int i = 0; i < sideLength; i++) {
9+
for (int j = 0; j < sideLength; j++) {
10+
int num = 1;
11+
num *= (width - 1 - i) / sideLength + 1;
12+
num *= (height - 1 - j) / sideLength + 1;
13+
nodes.add(num);
14+
}
15+
}
16+
17+
int res = 0;
18+
nodes.sort(Comparator.reverseOrder());
19+
for (int i = 0; i < maxOnes; i++) {
20+
res += nodes.get(i);
21+
}
22+
return res;
23+
}
24+
}
25+
/*
26+
$1183. 矩阵中 1 的最大数量
27+
https://leetcode.cn/problems/maximum-number-of-ones/
28+
29+
现在有一个尺寸为 width * height 的矩阵 M,矩阵中的每个单元格的值不是 0 就是 1。
30+
而且矩阵 M 中每个大小为 sideLength * sideLength 的 正方形 子阵中,1 的数量不得超过 maxOnes。
31+
请你设计一个算法,计算矩阵中最多可以有多少个 1。
32+
提示:
33+
1 <= width, height <= 100
34+
1 <= sideLength <= width, height
35+
0 <= maxOnes <= sideLength * sideLength
36+
37+
计算左上角正方形的每个格子在整个矩形中有多少个等效位置,取等效位置最多的前 maxOnes 个即可。
38+
https://leetcode.cn/problems/maximum-number-of-ones/solution/kao-lu-zui-zuo-shang-jiao-de-zheng-fang-xing-mei-g/
39+
*/
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import java.util.PriorityQueue;
2+
3+
public class Solution1199 {
4+
public int minBuildTime(int[] blocks, int split) {
5+
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
6+
for (int block : blocks) {
7+
minHeap.add(block);
8+
}
9+
10+
while (minHeap.size() > 1) {
11+
int min = minHeap.remove();
12+
int secMin = minHeap.remove();
13+
minHeap.add(split + secMin);
14+
}
15+
return minHeap.remove();
16+
}
17+
}
18+
/*
19+
$1199. 建造街区的最短时间
20+
https://leetcode.cn/problems/minimum-time-to-build-blocks/
21+
22+
你是个城市规划工作者,手里负责管辖一系列的街区。在这个街区列表中 blocks[i] = t 意味着第 i 个街区需要 t 个单位的时间来建造。
23+
由于一个街区只能由一个工人来完成建造。
24+
所以,一个工人要么需要再召唤一个工人(工人数增加 1);要么建造完一个街区后回家。这两个决定都需要花费一定的时间。
25+
一个工人再召唤一个工人所花费的时间由整数 split 给出。
26+
注意:如果两个工人同时召唤别的工人,那么他们的行为是并行的,所以时间花费仍然是 split。
27+
最开始的时候只有 一个 工人,请你最后输出建造完所有街区所需要的最少时间。
28+
提示:
29+
1 <= blocks.length <= 1000
30+
1 <= blocks[i] <= 10^5
31+
1 <= split <= 100
32+
33+
哈夫曼算法思想
34+
https://leetcode.cn/problems/minimum-time-to-build-blocks/solution/cong-fen-lie-gong-ren-dao-he-bing-jie-qu-tan-xin-c/
35+
*/
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution1153Tests {
5+
private final Solution1153 solution1153 = new Solution1153();
6+
7+
@Test
8+
public void example1() {
9+
String str1 = "aabcc";
10+
String str2 = "ccdee";
11+
Assertions.assertTrue(solution1153.canConvert(str1, str2));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
String str1 = "leetcode";
17+
String str2 = "codeleet";
18+
Assertions.assertFalse(solution1153.canConvert(str1, str2));
19+
}
20+
}

0 commit comments

Comments
 (0)