@@ -985,7 +985,7 @@ public String frequencySort(String s) {
985
985
986
986
<div align =" center " > <img src =" ../pics//3b49dd67-2c40-4b81-8ad2-7bbb1fe2fcbd.png " /> </div ><br >
987
987
988
- ** 对颜色进行排序 **
988
+ ** 按颜色进行排序 **
989
989
990
990
[ 75. Sort Colors (Medium)] ( https://leetcode.com/problems/sort-colors/description/ )
991
991
@@ -994,6 +994,8 @@ Input: [2,0,2,1,1,0]
994
994
Output: [0,0,1,1,2,2]
995
995
```
996
996
997
+ 题目描述:只有 0/1/2 三种颜色。
998
+
997
999
``` java
998
1000
public void sortColors(int [] nums) {
999
1001
int zero = - 1 , one = 0 , two = nums. length;
@@ -1040,7 +1042,7 @@ private void swap(int[] nums, int i, int j) {
1040
1042
- 4 -> {}
1041
1043
- 3 -> {}
1042
1044
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 只能求解无权图的最短路径。
1044
1046
1045
1047
在程序实现 BFS 时需要考虑以下问题:
1046
1048
@@ -1060,35 +1062,174 @@ private void swap(int[] nums, int i, int j) {
1060
1062
1061
1063
``` java
1062
1064
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 ));
1067
1069
int pathLength = 0 ;
1068
1070
while (! queue. isEmpty()) {
1069
1071
int size = queue. size();
1070
1072
pathLength++ ;
1071
1073
while (size-- > 0 ) {
1072
- Position cur = queue. poll();
1074
+ Pair< Integer , Integer > cur = queue. poll();
1073
1075
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;
1078
1082
queue. add(next);
1079
1083
}
1080
1084
}
1081
1085
}
1082
1086
return - 1 ;
1083
1087
}
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 的最短路径。
1084
1101
1085
- private class Position {
1086
- int r, c;
1102
+ 本题也可以用动态规划求解,在之后动态规划部分中会再次出现。
1087
1103
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
+ }
1091
1231
}
1232
+ return 0 ;
1092
1233
}
1093
1234
```
1094
1235
0 commit comments