Skip to content

Commit 5cd1eec

Browse files
Merge pull request youngyangyang04#2871 from curforever/master
修改0383.赎金信.md的时间复杂度分析、添加0018.四数之和.md的Java版本的注释、添加0459.重复的子字符串.md的Java版本二前缀表不减一、修改0020.有效的括号.md的Java版本一处注释、修改二叉树的统一迭代法.md的Java版本注释笔误
2 parents 7502fc9 + b764a12 commit 5cd1eec

5 files changed

+51
-9
lines changed

problems/0018.四数之和.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ public class Solution {
253253
for (int k = 0; k < nums.length; k++) {
254254
// 剪枝处理
255255
if (nums[k] > target && nums[k] >= 0) {
256-
break;
256+
break; // 此处的break可以等价于return result;
257257
}
258258
// 对nums[k]去重
259259
if (k > 0 && nums[k] == nums[k - 1]) {
@@ -262,7 +262,7 @@ public class Solution {
262262
for (int i = k + 1; i < nums.length; i++) {
263263
// 第二级剪枝
264264
if (nums[k] + nums[i] > target && nums[k] + nums[i] >= 0) {
265-
break;
265+
break; // 注意是break到上一级for循环,如果直接return result;会有遗漏
266266
}
267267
// 对nums[i]去重
268268
if (i > k + 1 && nums[i] == nums[i - 1]) {

problems/0020.有效的括号.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class Solution {
166166
deque.pop();
167167
}
168168
}
169-
//最后判断栈中元素是否匹配
169+
//遍历结束,如果栈为空,则括号全部匹配
170170
return deque.isEmpty();
171171
}
172172
}
@@ -578,3 +578,4 @@ impl Solution {
578578
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
579579
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
580580
</a>
581+

problems/0383.赎金信.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public:
104104
};
105105
```
106106

107-
* 时间复杂度: O(n)
107+
* 时间复杂度: O(m+n),其中m表示ransomNote的长度,n表示magazine的长度
108108
* 空间复杂度: O(1)
109109

110110

@@ -470,3 +470,4 @@ bool canConstruct(char* ransomNote, char* magazine) {
470470
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
471471
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
472472
</a>
473+

problems/0459.重复的子字符串.md

+41-1
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,8 @@ public:
390390
391391
### Java:
392392
393+
(版本一) 前缀表 减一
394+
393395
```java
394396
class Solution {
395397
public boolean repeatedSubstringPattern(String s) {
@@ -420,6 +422,45 @@ class Solution {
420422
}
421423
```
422424

425+
(版本二) 前缀表 不减一
426+
427+
```java
428+
/*
429+
* 充分条件:如果字符串s是由重复子串组成的,那么它的最长相等前后缀不包含的子串一定是s的最小重复子串。
430+
* 必要条件:如果字符串s的最长相等前后缀不包含的子串是s的最小重复子串,那么s必然是由重复子串组成的。
431+
* 推得:当字符串s的长度可以被其最长相等前后缀不包含的子串的长度整除时,不包含的子串就是s的最小重复子串。
432+
*
433+
* 时间复杂度:O(n)
434+
* 空间复杂度:O(n)
435+
*/
436+
class Solution {
437+
public boolean repeatedSubstringPattern(String s) {
438+
// if (s.equals("")) return false;
439+
// 边界判断(可以去掉,因为题目给定范围是1 <= s.length <= 10^4)
440+
int n = s.length();
441+
442+
// Step 1.构建KMP算法的前缀表
443+
int[] next = new int[n]; // 前缀表的值表示 以该位置结尾的字符串的最长相等前后缀的长度
444+
int j = 0;
445+
next[0] = 0;
446+
for (int i = 1; i < n; i++) {
447+
while (j > 0 && s.charAt(i) != s.charAt(j)) // 只要前缀后缀还不一致,就根据前缀表回退j直到起点为止
448+
j = next[j - 1];
449+
if (s.charAt(i) == s.charAt(j))
450+
j++;
451+
next[i] = j;
452+
}
453+
454+
// Step 2.判断重复子字符串
455+
if (next[n - 1] > 0 && n % (n - next[n - 1]) == 0) { // 当字符串s的长度可以被其最长相等前后缀不包含的子串的长度整除时
456+
return true; // 不包含的子串就是s的最小重复子串
457+
} else {
458+
return false;
459+
}
460+
}
461+
}
462+
```
463+
423464
### Python:
424465

425466
(版本一) 前缀表 减一
@@ -930,4 +971,3 @@ bool repeatedSubstringPattern(char* s) {
930971
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
931972
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
932973
</a>
933-

problems/二叉树的统一迭代法.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ class Solution {
238238
while (!st.empty()) {
239239
TreeNode node = st.peek();
240240
if (node != null) {
241-
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
241+
st.pop(); // 将该节点弹出,避免重复操作,下面再将右左中节点添加到栈中(前序遍历-中左右,入栈顺序右左中)
242242
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
243243
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
244244
st.push(node); // 添加中节点
@@ -266,11 +266,10 @@ public List<Integer> inorderTraversal(TreeNode root) {
266266
while (!st.empty()) {
267267
TreeNode node = st.peek();
268268
if (node != null) {
269-
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
269+
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中(中序遍历-左中右,入栈顺序右中左)
270270
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
271271
st.push(node); // 添加中节点
272272
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
273-
274273
if (node.left!=null) st.push(node.left); // 添加左节点(空节点不入栈)
275274
} else { // 只有遇到空节点的时候,才将下一个节点放进结果集
276275
st.pop(); // 将空节点弹出
@@ -294,7 +293,7 @@ class Solution {
294293
while (!st.empty()) {
295294
TreeNode node = st.peek();
296295
if (node != null) {
297-
st.pop(); // 将该节点弹出,避免重复操作,下面再将右中左节点添加到栈中
296+
st.pop(); // 将该节点弹出,避免重复操作,下面再将中右左节点添加到栈中(后序遍历-左右中,入栈顺序中右左)
298297
st.push(node); // 添加中节点
299298
st.push(null); // 中节点访问过,但是还没有处理,加入空节点做为标记。
300299
if (node.right!=null) st.push(node.right); // 添加右节点(空节点不入栈)
@@ -975,3 +974,4 @@ public IList<int> PostorderTraversal(TreeNode root)
975974
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
976975
<img src="../pics/网站星球宣传海报.jpg" width="1000"/>
977976
</a>
977+

0 commit comments

Comments
 (0)