Skip to content

Commit 1804fbe

Browse files
JavaScalaDeveloperJavaScalaDeveloper
authored andcommitted
solution:131~158
1 parent 6839a1c commit 1804fbe

File tree

16 files changed

+286
-118
lines changed

16 files changed

+286
-118
lines changed

change/note/unknow.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@
1717
- 97 归并排序
1818
- 126 单词接龙
1919
- 127
20-
- 130 被围绕的区域
20+
- 130 被围绕的区域
21+
- 131 回文子串
22+
- 137 二进制

solution/0100-0199/0130.Surrounded Regions/README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@
4040

4141
DFS、BFS、并查集均可。
4242

43-
DFS:
44-
45-
并查集:
46-
4743
### **Java**
4844

4945
DFS:

solution/0100-0199/0130.Surrounded Regions/Solution.java

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
package com.solution._0130;
2-
import change.datastructure.*;
3-
import java.util.*;
2+
43
public class Solution {
54
private char[][] board;
65
private int m;
76
private int n;
87

8+
public static void main(String[] args) {
9+
char[][] chars = {
10+
{'X', 'X', 'X', 'X'},
11+
{'X', 'O', 'O', 'X'},
12+
{'X', 'X', 'O', 'X'},
13+
{'X', 'O', 'X', 'X'}
14+
};
15+
// Solution solution = new Solution();
16+
// solution.solve(chars);
17+
// for (char[] aChar : chars) {
18+
// for (int j = 0; j < chars[0].length; j++) {
19+
// System.out.println(aChar[j]);
20+
// }
21+
// }
22+
Solution2 solution2 = new Solution2();
23+
solution2.solve(chars);
24+
for (char[] aChar : chars) {
25+
for (int j = 0; j < chars[0].length; j++) {
26+
System.out.println(aChar[j]);
27+
}
28+
}
29+
}
30+
931
public void solve(char[][] board) {
1032
m = board.length;
1133
n = board[0].length;
@@ -39,4 +61,44 @@ private void dfs(int i, int j) {
3961
}
4062
}
4163
}
64+
65+
private static class Solution2 {
66+
public void solve(char[][] board) {
67+
if (board == null || board.length == 0 || board[0].length == 0) {
68+
return;
69+
}
70+
int m = board.length, n = board[0].length;
71+
// 标记所有与边界相连的 'O'
72+
for (int i = 0; i < m; i++) {
73+
dfs(board, i, 0);
74+
dfs(board, i, n - 1);
75+
}
76+
for (int j = 0; j < n; j++) {
77+
dfs(board, 0, j);
78+
dfs(board, m - 1, j);
79+
}
80+
// 处理未被标记的 'O'
81+
for (int i = 0; i < m; i++) {
82+
for (int j = 0; j < n; j++) {
83+
if (board[i][j] == 'O') {
84+
board[i][j] = 'X';
85+
} else if (board[i][j] == '#') {
86+
board[i][j] = 'O';
87+
}
88+
}
89+
}
90+
}
91+
92+
private void dfs(char[][] board, int i, int j) {
93+
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != 'O') {
94+
return;
95+
}
96+
board[i][j] = '#'; // 标记为特殊字符
97+
dfs(board, i - 1, j);
98+
dfs(board, i + 1, j);
99+
dfs(board, i, j - 1);
100+
dfs(board, i, j + 1);
101+
}
102+
103+
}
42104
}

solution/0100-0199/0131.Palindrome Partitioning/Solution.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
package com.solution._0131;
2-
import change.datastructure.*;
3-
import java.util.*;
2+
3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.List;
6+
47
public class Solution {
58
private boolean[][] dp;
69
private List<List<String>> ans;
710
private int n;
811

12+
public static void main(String[] args) {
13+
Solution solution = new Solution();
14+
String s = "aab";
15+
List<List<String>> res = solution.partition(s);
16+
System.out.println(res);
17+
}
18+
919
public List<List<String>> partition(String s) {
1020
ans = new ArrayList<>();
1121
n = s.length();
@@ -35,4 +45,42 @@ private void dfs(String s, int i, List<String> t) {
3545
}
3646
}
3747
}
48+
49+
/*
50+
回溯算法
51+
具体来说,我们可以枚举每个可能的分割位置,判断从该位置到当前字符串结尾的子串是否为回文串,如果是,则将其加入路径中,并继续搜索剩下的部分。如果搜索到字符串结尾,则将当前路径加入结果集。
52+
*/
53+
public List<List<String>> partition2(String s) {
54+
List<List<String>> result = new ArrayList<>();
55+
if (s == null || s.length() == 0) {
56+
return result;
57+
}
58+
List<String> path = new ArrayList<>();
59+
backtrack2(s, 0, path, result);
60+
return result;
61+
}
62+
63+
private void backtrack2(String s, int start, List<String> path, List<List<String>> result) {
64+
if (start == s.length()) { // 到达字符串结尾
65+
result.add(new ArrayList<>(path));
66+
return;
67+
}
68+
for (int i = start; i < s.length(); i++) {
69+
if (isPalindrome(s, start, i)) { // 从start到i的子串是回文串
70+
path.add(s.substring(start, i + 1));
71+
backtrack2(s, i + 1, path, result);
72+
path.remove(path.size() - 1); // 回溯
73+
}
74+
}
75+
}
76+
77+
private boolean isPalindrome(String s, int start, int end) { // 判断子串是否为回文串
78+
while (start < end) {
79+
if (s.charAt(start++) != s.charAt(end--)) {
80+
return false;
81+
}
82+
}
83+
return true;
84+
}
85+
3886
}

solution/0100-0199/0133.Clone Graph/Solution.java

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,3 @@
1-
/*
2-
// Definition for a Node.
3-
package com.solution._0133;
4-
import change.datastructure.*;
5-
import java.util.*;
6-
public class Node {
7-
public int val;
8-
public List<Node> neighbors;
9-
public Node() {
10-
val = 0;
11-
neighbors = new ArrayList<Node>();
12-
}
13-
public Node(int _val) {
14-
val = _val;
15-
neighbors = new ArrayList<Node>();
16-
}
17-
public Node(int _val, ArrayList<Node> _neighbors) {
18-
val = _val;
19-
neighbors = _neighbors;
20-
}
21-
}
22-
*/
23-
241
package com.solution._0133;
252

263
import java.util.ArrayList;
@@ -31,6 +8,9 @@ public Node(int _val, ArrayList<Node> _neighbors) {
318
public class Solution {
329
private Map<Node, Node> visited = new HashMap<>();
3310

11+
public static void main(String[] args) {
12+
Solution solution = new Solution();
13+
}
3414
public Node cloneGraph(Node node) {
3515
if (node == null) {
3616
return null;

solution/0100-0199/0134.Gas Station/Solution.java

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package com.solution._0134;
2-
import change.datastructure.*;
3-
import java.util.*;
2+
43
public class Solution {
4+
public static void main(String[] args) {
5+
Solution solution = new Solution();
6+
int[] gas = new int[]{1, 2, 3, 4, 5}, cost = {3, 4, 5, 1, 2};
7+
int res = solution.canCompleteCircuit(gas, cost);
8+
int res2 = solution.canCompleteCircuit2(gas, cost);
9+
System.out.println(res);
10+
System.out.println(res2);
11+
}
12+
513
public int canCompleteCircuit(int[] gas, int[] cost) {
614
int n = gas.length;
715
int i = n - 1, j = n - 1;
8-
int cnt = 0, s = 0;
16+
int cnt = 0, s = 0;//步行距离和剩余油量
917
while (cnt < n) {
1018
s += gas[j] - cost[j];
1119
++cnt;
@@ -18,4 +26,33 @@ public int canCompleteCircuit(int[] gas, int[] cost) {
1826
}
1927
return s < 0 ? -1 : i;
2028
}
29+
30+
/*
31+
对于每个节点 i,我们计算从该节点出发能否到达节点 i+1。如果能够到达,则转移到 i+1 继续判断;如果不能到达,则从节点 i+1 重新开始计算。
32+
此外,我们还需要维护一个变量 sum,记录从当前节点出发到下一站剩余的油量。如果 sum 小于 0,则说明从当前节点出发无法到达下一站,需要重新选择起点。
33+
*/
34+
public int canCompleteCircuit2(int[] gas, int[] cost) {
35+
int n = gas.length;
36+
int i = 0; // 起点
37+
while (i < n) {
38+
int sum = 0; // 从当前节点出发到下一站剩余的油量
39+
int j = i;
40+
while (true) {
41+
sum += gas[j] - cost[j];
42+
if (sum < 0) { // 从当前节点出发无法到达下一站
43+
break;
44+
}
45+
j = (j + 1) % n;//j为终点
46+
if (j == i) { // 能够绕一圈回到起点
47+
return i;
48+
}
49+
}
50+
i = j + 1; // 从下一个节点重新开始
51+
if (i >= n) {
52+
break;
53+
}
54+
}
55+
return -1;
56+
}
57+
2158
}

solution/0100-0199/0135.Candy/Solution.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@ public int candy(int[] ratings) {
66
int n = ratings.length;
77
int[] left = new int[n];
88
int[] right = new int[n];
9+
//每个孩子最少1个
910
Arrays.fill(left, 1);
1011
Arrays.fill(right, 1);
12+
//右边孩子比左边孩子多1个
1113
for (int i = 1; i < n; ++i) {
1214
if (ratings[i] > ratings[i - 1]) {
1315
left[i] = left[i - 1] + 1;
1416
}
1517
}
18+
//左边孩子比右边孩子多1个
1619
for (int i = n - 2; i >= 0; --i) {
1720
if (ratings[i] > ratings[i + 1]) {
1821
right[i] = right[i + 1] + 1;

solution/0100-0199/0140.Word Break II/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<p><strong class="example">示例 1:</strong></p>
1010

1111
<pre>
12-
<strong>输入:</strong>s = "<code>catsanddog</code>", wordDict = <code>["cat","cats","and","sand","dog"]</code>
12+
<strong>输入:</strong>s = <code>"catsanddog"</code>, wordDict = <code>["cat","cats","and","sand","dog"]</code>
1313
<strong>输出:</strong><code>["cats and dog","cat sand dog"]</code>
1414
</pre>
1515

solution/0100-0199/0140.Word Break II/Solution.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,19 @@
11
package com.solution._0140;
2-
import change.datastructure.*;
2+
33
import java.util.*;
44
import java.util.stream.Collectors;
55

66
public class Solution {
77
private Trie trie = new Trie();
88

9+
public static void main(String[] args) {
10+
Solution solution = new Solution();
11+
String s = "catsanddog";
12+
String[] wordDict = new String[]{"cat", "cats", "and", "sand", "dog"};
13+
List<String> res = solution.wordBreak2(s, Arrays.asList(wordDict));
14+
System.out.println(res);
15+
}
16+
917
public List<String> wordBreak(String s, List<String> wordDict) {
1018
for (String w : wordDict) {
1119
trie.insert(w);
@@ -30,7 +38,42 @@ private List<List<String>> dfs(String s) {
3038
}
3139
return res;
3240
}
41+
42+
/*
43+
定义一个递归函数 dfs(i) 表示从 s 的第 i 个字符开始构建匹配的句子,并返回所有可行的句子。由于不同的起始位置可能构成相同的句子,因此我们使用一个哈希表 memo 记录已经计算过的起始位置以及它们所对应的句子列表。
44+
具体来说,在递归函数中,我们首先检查 memo 是否包含当前起始位置 i,如果包含,则直接返回 memo[i];否则,我们枚举从 i 开始的所有可能的单词,并递归处理剩余的部分,将结果拼接到当前单词上。如果单词可以匹配剩余部分,并且剩余部分也可以构成匹配的句子,那么将其加入结果列表中,并添加到 memo 中。
45+
时间复杂度和空间复杂度均为 O(n^3)
46+
*/
47+
public List<String> wordBreak2(String s, List<String> wordDict) {
48+
Set<String> wordSet = new HashSet<>(wordDict);
49+
Map<Integer, List<String>> memo = new HashMap<>();
50+
return dfs(s, 0, wordSet, memo);
51+
}
52+
53+
private List<String> dfs(String s, int start, Set<String> wordSet, Map<Integer, List<String>> memo) {
54+
if (memo.containsKey(start)) { // 如果 memo 中已经有了该起点的结果,则直接返回
55+
return memo.get(start);
56+
}
57+
List<String> result = new ArrayList<>();
58+
if (start == s.length()) { // 到达字符串结尾
59+
result.add("");
60+
return result;
61+
}
62+
for (int end = start + 1; end <= s.length(); end++) {
63+
String word = s.substring(start, end);
64+
if (wordSet.contains(word)) {
65+
List<String> nexts = dfs(s, end, wordSet, memo); // 递归处理后面部分
66+
for (String next : nexts) {
67+
result.add(word + (next.isEmpty() ? "" : " ") + next);
68+
}
69+
}
70+
}
71+
memo.put(start, result); // 将结果添加到 memo 中缓存
72+
return result;
73+
}
74+
3375
}
76+
3477
class Trie {
3578
Trie[] children = new Trie[26];
3679
boolean isEnd;

solution/0100-0199/0144.Binary Tree Preorder Traversal/README.md

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,6 @@ Morris 遍历无需使用栈,空间复杂度为 O(1)。核心思想是:
8383
- 若前驱节点 prev 的右子树不为空,将前驱节点右子树指向空(即解除 prev 与 root 的指向关系),并将当前节点更新为 `root.right`
8484
3. 循环以上步骤,直至二叉树节点为空,遍历结束。
8585

86-
递归:
87-
88-
栈实现非递归:
89-
90-
Morris 遍历:
91-
9286
### **Java**
9387

9488
递归:

0 commit comments

Comments
 (0)