Skip to content

Commit ba0bfeb

Browse files
committed
auto commit
1 parent b5f3fe0 commit ba0bfeb

File tree

1 file changed

+157
-16
lines changed

1 file changed

+157
-16
lines changed

notes/Leetcode 题解.md

Lines changed: 157 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,7 @@ public String frequencySort(String s) {
985985

986986
<div align="center"> <img src="../pics//3b49dd67-2c40-4b81-8ad2-7bbb1fe2fcbd.png"/> </div><br>
987987

988-
**对颜色进行排序**
988+
**按颜色进行排序**
989989

990990
[75. Sort Colors (Medium)](https://leetcode.com/problems/sort-colors/description/)
991991

@@ -994,6 +994,8 @@ Input: [2,0,2,1,1,0]
994994
Output: [0,0,1,1,2,2]
995995
```
996996

997+
题目描述:只有 0/1/2 三种颜色。
998+
997999
```java
9981000
public void sortColors(int[] nums) {
9991001
int zero = -1, one = 0, two = nums.length;
@@ -1040,7 +1042,7 @@ private void swap(int[] nums, int i, int j) {
10401042
- 4 -> {}
10411043
- 3 -> {}
10421044

1043-
可以看到,每一轮遍历的节点都与根节点距离相同。设 d<sub>i</sub> 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 d<sub>i</sub><=d<sub>j</sub>。利用这个结论,可以求解最短路径等 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径。
1045+
可以看到,每一轮遍历的节点都与根节点距离相同。设 d<sub>i</sub> 表示第 i 个节点与根节点的距离,推导出一个结论:对于先遍历的节点 i 与后遍历的节点 j,有 d<sub>i</sub><=d<sub>j</sub>。利用这个结论,可以求解最短路径等 **最优解** 问题:第一次遍历到目的节点,其所经过的路径为最短路径。应该注意的是,使用 BFS 只能求解无权图的最短路径。
10441046

10451047
在程序实现 BFS 时需要考虑以下问题:
10461048

@@ -1060,35 +1062,174 @@ private void swap(int[] nums, int i, int j) {
10601062

10611063
```java
10621064
public int minPathLength(int[][] grids, int tr, int tc) {
1063-
int[][] direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
1064-
int m = grids.length, n = grids[0].length;
1065-
Queue<Position> queue = new LinkedList<>();
1066-
queue.add(new Position(0, 0));
1065+
final int[][] direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
1066+
final int m = grids.length, n = grids[0].length;
1067+
Queue<Pair<Integer, Integer>> queue = new LinkedList<>();
1068+
queue.add(new Pair(0, 0));
10671069
int pathLength = 0;
10681070
while (!queue.isEmpty()) {
10691071
int size = queue.size();
10701072
pathLength++;
10711073
while (size-- > 0) {
1072-
Position cur = queue.poll();
1074+
Pair<Integer, Integer> cur = queue.poll();
10731075
for (int[] d : direction) {
1074-
Position next = new Position(cur.r + d[0], cur.c + d[1]);
1075-
if (next.r < 0 || next.r >= m || next.c < 0 || next.c >= n) continue;
1076-
grids[next.r][next.c] = 0;
1077-
if (next.r == tr && next.c == tc) return pathLength;
1076+
Pair<Integer, Integer> next = new Pair(cur.getKey() + d[0], cur.getValue() + d[1]);
1077+
if (next.getKey() < 0 || next.getValue() >= m || next.getKey() < 0 || next.getValue() >= n)
1078+
continue;
1079+
grids[next.getKey()][next.getValue()] = 0; // 标记
1080+
if (next.getKey() == tr && next.getValue() == tc)
1081+
return pathLength;
10781082
queue.add(next);
10791083
}
10801084
}
10811085
}
10821086
return -1;
10831087
}
1088+
```
1089+
1090+
**组成整数的最小平方数数量**
1091+
1092+
[279. Perfect Squares (Medium)](https://leetcode.com/problems/perfect-squares/description/)
1093+
1094+
```html
1095+
For example, given n = 12, return 3 because 12 = 4 + 4 + 4; given n = 13, return 2 because 13 = 4 + 9.
1096+
```
1097+
1098+
可以将每个整数看成图中的一个节点,如果两个整数只差为一个平方数,那么这两个整数所在的节点就有一条边。
1099+
1100+
要求解最小的平方数数量,就是求解从节点 n 到节点 0 的最短路径。
10841101

1085-
private class Position {
1086-
int r, c;
1102+
本题也可以用动态规划求解,在之后动态规划部分中会再次出现。
10871103

1088-
Position(int r, int c) {
1089-
this.r = r;
1090-
this.c = c;
1104+
```java
1105+
public int numSquares(int n) {
1106+
List<Integer> squares = generateSquares(n);
1107+
Queue<Integer> queue = new LinkedList<>();
1108+
boolean[] marked = new boolean[n + 1];
1109+
queue.add(n);
1110+
marked[n] = true;
1111+
int num = 0;
1112+
while (!queue.isEmpty()) {
1113+
int size = queue.size();
1114+
num++;
1115+
while (size-- > 0) {
1116+
int cur = queue.poll();
1117+
for (int s : squares) {
1118+
int next = cur - s;
1119+
if (next < 0)
1120+
break;
1121+
if (next == 0)
1122+
return num;
1123+
if (marked[next])
1124+
continue;
1125+
marked[next] = true;
1126+
queue.add(cur - s);
1127+
}
1128+
}
1129+
}
1130+
return n;
1131+
}
1132+
1133+
private List<Integer> generateSquares(int n) {
1134+
List<Integer> squares = new ArrayList<>();
1135+
int square = 1;
1136+
int diff = 3;
1137+
while (square <= n) {
1138+
squares.add(square);
1139+
square += diff;
1140+
diff += 2;
1141+
}
1142+
return squares;
1143+
}
1144+
```
1145+
1146+
**最短单词路径**
1147+
1148+
[127. Word Ladder (Medium)](https://leetcode.com/problems/word-ladder/description/)
1149+
1150+
```html
1151+
Input:
1152+
beginWord = "hit",
1153+
endWord = "cog",
1154+
wordList = ["hot","dot","dog","lot","log","cog"]
1155+
1156+
Output: 5
1157+
1158+
Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
1159+
return its length 5.
1160+
```
1161+
1162+
```html
1163+
Input:
1164+
beginWord = "hit"
1165+
endWord = "cog"
1166+
wordList = ["hot","dot","dog","lot","log"]
1167+
1168+
Output: 0
1169+
1170+
Explanation: The endWord "cog" is not in wordList, therefore no possible transformation.
1171+
```
1172+
1173+
题目描述:要找出一条从 beginWord 到 endWord 的最短路径,每次移动规定为改变一个字符,并且改变之后的字符串必须在 wordList 中。
1174+
1175+
```java
1176+
public int ladderLength(String beginWord, String endWord, List<String> wordList) {
1177+
wordList.add(beginWord);
1178+
int N = wordList.size();
1179+
int start = N - 1;
1180+
int end = 0;
1181+
while (end < N && !wordList.get(end).equals(endWord))
1182+
end++;
1183+
if (end == N)
1184+
return 0;
1185+
List<Integer>[] graphic = buildGraphic(wordList);
1186+
return getShortestPath(graphic, start, end);
1187+
}
1188+
1189+
private List<Integer>[] buildGraphic(List<String> wordList) {
1190+
int N = wordList.size();
1191+
List<Integer>[] graphic = new List[N];
1192+
for (int i = 0; i < N; i++) {
1193+
graphic[i] = new ArrayList<>();
1194+
for (int j = 0; j < N; j++) {
1195+
if (isConnect(wordList.get(i), wordList.get(j)))
1196+
graphic[i].add(j);
1197+
}
1198+
}
1199+
return graphic;
1200+
}
1201+
1202+
private boolean isConnect(String s1, String s2) {
1203+
int diffCnt = 0;
1204+
for (int i = 0; i < s1.length() && diffCnt <= 1; i++) {
1205+
if (s1.charAt(i) != s2.charAt(i))
1206+
diffCnt++;
1207+
}
1208+
return diffCnt == 1;
1209+
}
1210+
1211+
private int getShortestPath(List<Integer>[] graphic, int start, int end) {
1212+
Queue<Integer> queue = new LinkedList<>();
1213+
boolean[] marked = new boolean[graphic.length];
1214+
queue.add(start);
1215+
marked[start] = true;
1216+
int path = 1;
1217+
while (!queue.isEmpty()) {
1218+
int size = queue.size();
1219+
path++;
1220+
while (size-- > 0) {
1221+
int cur = queue.poll();
1222+
for (int next : graphic[cur]) {
1223+
if (next == end)
1224+
return path;
1225+
if (marked[next])
1226+
continue;
1227+
marked[next] = true;
1228+
queue.add(next);
1229+
}
1230+
}
10911231
}
1232+
return 0;
10921233
}
10931234
```
10941235

0 commit comments

Comments
 (0)