Skip to content

Commit e5685f7

Browse files
committed
533-545-604-624-656-663-734-760-800-966 (10)
1 parent d5e867e commit e5685f7

File tree

20 files changed

+801
-0
lines changed

20 files changed

+801
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class Solution533 {
5+
// 531
6+
public int findBlackPixel(char[][] picture, int target) {
7+
int m = picture.length;
8+
int n = picture[0].length;
9+
// 预处理
10+
int[] cols = new int[n];
11+
for (char[] chars : picture) {
12+
for (int j = 0; j < n; j++) {
13+
if (chars[j] == 'B') {
14+
cols[j]++;
15+
}
16+
}
17+
}
18+
// 相同行进行合并计数 [B的数量, 相同行数]
19+
Map<String, int[]> cntMap = new HashMap<>();
20+
for (char[] chars : picture) {
21+
String key = new String(chars);
22+
if (cntMap.containsKey(key)) {
23+
cntMap.get(key)[1]++;
24+
} else {
25+
int cntB = 0;
26+
for (char ch : chars) {
27+
if (ch == 'B') {
28+
cntB++;
29+
}
30+
}
31+
cntMap.put(key, new int[]{cntB, 1});
32+
}
33+
}
34+
35+
int res = 0;
36+
for (Map.Entry<String, int[]> entry : cntMap.entrySet()) {
37+
String key = entry.getKey();
38+
int[] tuple = entry.getValue();
39+
// 行满足要求
40+
if (tuple[0] == target && tuple[1] == target) {
41+
for (int j = 0; j < n; j++) {
42+
// 列满足要求
43+
if (key.charAt(j) == 'B' && cols[j] == target) {
44+
res++;
45+
}
46+
}
47+
}
48+
}
49+
return res * target;
50+
}
51+
}
52+
/*
53+
$533. 孤独像素 II
54+
https://leetcode.cn/problems/lonely-pixel-ii/
55+
56+
给你一个大小为 m x n 的二维字符数组 picture ,表示一张黑白图像,数组中的 'B' 表示黑色像素,'W' 表示白色像素。另给你一个整数 target ,请你找出并返回符合规则的 黑色 孤独像素的数量。
57+
黑色孤独像素是指位于某一特定位置 (r, c) 的字符 'B' ,其中:
58+
- 行 r 和列 c 中的黑色像素恰好有 target 个。
59+
- 列 c 中所有黑色像素所在的行必须和行 r 完全相同。
60+
提示:
61+
m == picture.length
62+
n == picture[i].length
63+
1 <= m, n <= 200
64+
picture[i][j] 为 'W' 或 'B'
65+
1 <= target <= min(m, n)
66+
67+
难度升级,条件二的意思是 满足要求的行全部相同,因此要将相同的行进行预处理。
68+
相似题目: $531. 孤独像素 I
69+
https://leetcode.cn/problems/lonely-pixel-i/
70+
*/
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import java.util.ArrayDeque;
2+
import java.util.ArrayList;
3+
import java.util.Deque;
4+
import java.util.List;
5+
6+
public class Solution545 {
7+
public List<Integer> boundaryOfBinaryTree(TreeNode root) {
8+
List<Integer> resList = new ArrayList<>();
9+
if (root == null) {
10+
return resList;
11+
}
12+
13+
if (!isLeaf(root)) {
14+
resList.add(root.val);
15+
}
16+
TreeNode t = root.left;
17+
while (t != null) {
18+
if (!isLeaf(t)) {
19+
resList.add(t.val);
20+
}
21+
if (t.left != null) {
22+
t = t.left;
23+
} else {
24+
t = t.right;
25+
}
26+
}
27+
addLeaves(root, resList);
28+
29+
Deque<Integer> stack = new ArrayDeque<>();
30+
t = root.right;
31+
while (t != null) {
32+
if (!isLeaf(t)) {
33+
stack.push(t.val);
34+
}
35+
if (t.right != null) {
36+
t = t.right;
37+
} else {
38+
t = t.left;
39+
}
40+
}
41+
while (!stack.isEmpty()) {
42+
resList.add(stack.pop());
43+
}
44+
return resList;
45+
}
46+
47+
private boolean isLeaf(TreeNode node) {
48+
return node.left == null && node.right == null;
49+
}
50+
51+
private void addLeaves(TreeNode node, List<Integer> resList) {
52+
if (isLeaf(node)) {
53+
resList.add(node.val);
54+
} else {
55+
if (node.left != null) {
56+
addLeaves(node.left, resList);
57+
}
58+
if (node.right != null) {
59+
addLeaves(node.right, resList);
60+
}
61+
}
62+
}
63+
}
64+
/*
65+
$545. 二叉树的边界
66+
https://leetcode.cn/problems/boundary-of-binary-tree/
67+
68+
二叉树的 边界 是由 根节点 、左边界 、按从左到右顺序的 叶节点 和 逆序的右边界 ,按顺序依次连接组成。
69+
左边界 是满足下述定义的节点集合:
70+
- 根节点的左子节点在左边界中。如果根节点不含左子节点,那么左边界就为 空 。
71+
- 如果一个节点在左边界中,并且该节点有左子节点,那么它的左子节点也在左边界中。
72+
- 如果一个节点在左边界中,并且该节点 不含 左子节点,那么它的右子节点就在左边界中。
73+
- 最左侧的叶节点 不在 左边界中。
74+
右边界 定义方式与 左边界 相同,只是将左替换成右。即,右边界是根节点右子树的右侧部分;叶节点 不是 右边界的组成部分;如果根节点不含右子节点,那么右边界为 空 。
75+
叶节点 是没有任何子节点的节点。对于此问题,根节点 不是 叶节点。
76+
给你一棵二叉树的根节点 root ,按顺序返回组成二叉树 边界 的这些值。
77+
提示:
78+
树中节点的数目在范围 [1, 10^4] 内
79+
-1000 <= Node.val <= 1000
80+
81+
模拟。将问题划分成三个子问题:左边界、叶子节点和右边界。
82+
时间复杂度 O(n)
83+
空间复杂度 O(n)
84+
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution533Tests {
5+
private final Solution533 solution533 = new Solution533();
6+
7+
@Test
8+
public void example1() {
9+
char[][] picture = UtUtils.stringToChars2("""
10+
[["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","B","W","B","B","W"],["W","W","B","W","B","W"]]
11+
""");
12+
int target = 3;
13+
int expected = 6;
14+
Assertions.assertEquals(expected, solution533.findBlackPixel(picture, target));
15+
}
16+
17+
@Test
18+
public void example2() {
19+
char[][] picture = UtUtils.stringToChars2("""
20+
[["W","W","B"],["W","W","B"],["W","W","B"]]
21+
""");
22+
int target = 1;
23+
int expected = 0;
24+
Assertions.assertEquals(expected, solution533.findBlackPixel(picture, target));
25+
}
26+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
import java.util.List;
5+
6+
public class Solution545Tests {
7+
private final Solution545 solution545 = new Solution545();
8+
9+
@Test
10+
public void example1() {
11+
TreeNode root = TreeNode.buildTreeNode("[1,null,2,3,4]");
12+
List<Integer> expected = List.of(1, 3, 4, 2);
13+
Assertions.assertEquals(expected, solution545.boundaryOfBinaryTree(root));
14+
}
15+
16+
@Test
17+
public void example2() {
18+
TreeNode root = TreeNode.buildTreeNode("[1,2,3,4,5,6,null,null,null,7,8,9,10]");
19+
List<Integer> expected = List.of(1, 2, 4, 7, 8, 9, 10, 6, 3);
20+
Assertions.assertEquals(expected, solution545.boundaryOfBinaryTree(root));
21+
}
22+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
public class Solution604 {
2+
static class StringIterator {
3+
private final String compressedString;
4+
private final int N;
5+
private int iterator;
6+
private char ch;
7+
private int cnt;
8+
9+
public StringIterator(String compressedString) {
10+
this.compressedString = compressedString;
11+
N = compressedString.length();
12+
iterator = 0;
13+
ch = ' ';
14+
cnt = 0;
15+
}
16+
17+
public char next() {
18+
if (!hasNext()) {
19+
return ' ';
20+
}
21+
if (cnt == 0) {
22+
ch = compressedString.charAt(iterator++);
23+
while (iterator < N && Character.isDigit(compressedString.charAt(iterator))) {
24+
cnt = cnt * 10 + compressedString.charAt(iterator) - '0';
25+
iterator++;
26+
}
27+
}
28+
cnt--;
29+
return ch;
30+
}
31+
32+
public boolean hasNext() {
33+
return iterator != N || cnt != 0;
34+
}
35+
}
36+
}
37+
/*
38+
$604. 迭代压缩字符串
39+
https://leetcode.cn/problems/design-compressed-string-iterator/
40+
41+
设计并实现一个迭代压缩字符串的数据结构。给定的压缩字符串的形式是,每个字母后面紧跟一个正整数,表示该字母在原始未压缩字符串中出现的次数。
42+
设计一个数据结构,它支持如下两种操作: next 和 hasNext。
43+
- next() - 如果原始字符串中仍有未压缩字符,则返回下一个字符,否则返回空格。
44+
- hasNext() - 如果原始字符串中存在未压缩的的字母,则返回true,否则返回false。
45+
提示:
46+
1 <= compressedString.length <= 1000
47+
compressedString 由小写字母、大写字母和数字组成。
48+
在 compressedString 中,单个字符的重复次数在 [1,10 ^9] 范围内。
49+
next 和 hasNext 的操作数最多为 100 。
50+
51+
按需计算
52+
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.util.List;
2+
3+
public class Solution624 {
4+
public int maxDistance(List<List<Integer>> arrays) {
5+
int res = 0;
6+
int sz = arrays.size();
7+
List<Integer> array0 = arrays.get(0);
8+
int min = array0.get(0);
9+
int max = array0.get(array0.size() - 1);
10+
for (int i = 1; i < sz; i++) {
11+
List<Integer> arrayI = arrays.get(i);
12+
int minI = arrayI.get(0);
13+
int maxI = arrayI.get(arrayI.size() - 1);
14+
res = Math.max(res, Math.max(maxI - min, max - minI));
15+
min = Math.min(min, minI);
16+
max = Math.max(max, maxI);
17+
}
18+
return res;
19+
}
20+
}
21+
/*
22+
$624. 数组列表中的最大距离
23+
https://leetcode.cn/problems/maximum-distance-in-arrays/
24+
25+
给定 m 个数组,每个数组都已经按照升序排好序了。现在你需要从两个不同的数组中选择两个整数(每个数组选一个)并且计算它们的距离。
26+
两个整数 a 和 b 之间的距离定义为它们差的绝对值 |a-b| 。你的任务就是去找到最大距离
27+
示例 1:
28+
输入:
29+
[[1,2,3],
30+
[4,5],
31+
[1,2,3]]
32+
输出: 4
33+
解释:
34+
一种得到答案 4 的方法是从第一个数组或者第三个数组中选择 1,同时从第二个数组中选择 5 。
35+
注意:
36+
每个给定数组至少会有 1 个数字。列表中至少有两个非空数组。
37+
所有 m 个数组中的数字总数目在范围 [2, 10000] 内。
38+
m 个数组中所有整数的范围在 [-10000, 10000] 内。
39+
40+
扫描线
41+
*/
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
public class Solution656 {
6+
public List<Integer> cheapestJump(int[] coins, int maxJump) {
7+
int n = coins.length;
8+
int[] next = new int[n];
9+
Arrays.fill(next, -1);
10+
// f[i] 表示从位置 i 跳到末尾的最小花费
11+
long[] f = new long[n];
12+
13+
for (int i = n - 2; i >= 0; i--) {
14+
long minCost = Integer.MAX_VALUE;
15+
for (int j = i + 1; j <= i + maxJump && j < n; j++) {
16+
if (coins[i] != -1) {
17+
long cost = coins[i] + f[j];
18+
if (minCost > cost) {
19+
minCost = cost;
20+
next[i] = j;
21+
}
22+
}
23+
}
24+
f[i] = minCost;
25+
}
26+
27+
List<Integer> resList = new ArrayList<>();
28+
int i = 0;
29+
for (; i < n && next[i] != -1; i = next[i]) {
30+
resList.add(i + 1);
31+
}
32+
if (i == n - 1 && coins[i] != -1) {
33+
resList.add(n);
34+
} else {
35+
// 如果无法到达 N 位置,请返回一个空数组
36+
resList.clear();
37+
}
38+
return resList;
39+
}
40+
}
41+
/*
42+
$656. 金币路径
43+
https://leetcode.cn/problems/coin-path/
44+
45+
给定一个数组 A(下标从 1 开始)包含 N 个整数:A1,A2,……,AN 和一个整数 B。
46+
你可以从数组 A 中的任何一个位置(下标为 i)跳到下标 i+1,i+2,……,i+B 的任意一个可以跳到的位置上。
47+
如果你在下标为 i 的位置上,你需要支付 Ai 个金币。如果 Ai 是 -1,意味着下标为 i 的位置是不可以跳到的。
48+
现在,你希望花费最少的金币从数组 A 的 1 位置跳到 N 位置,你需要输出花费最少的路径,依次输出所有经过的下标(从 1 到 N)。
49+
如果有多种花费最少的方案,输出字典顺序最小的路径。
50+
如果无法到达 N 位置,请返回一个空数组。
51+
注释 :
52+
路径 Pa1,Pa2,……,Pan 是字典序小于 Pb1,Pb2,……,Pbm 的,当且仅当第一个 Pai 和 Pbi 不同的 i 满足 Pai < Pbi,如果不存在这样的 i 那么满足 n < m。
53+
A1 >= 0。 A2, ..., AN (如果存在) 的范围是 [-1, 100]。
54+
A 数组的长度范围 [1, 1000].
55+
B 的范围 [1, 100].
56+
57+
动态规划
58+
*/

0 commit comments

Comments
 (0)