Date: Mon, 21 Nov 2022 11:47:40 +0800
Subject: [PATCH 43/62] =?UTF-8?q?Update=201254.=E7=BB=9F=E8=AE=A1=E5=B0=81?=
=?UTF-8?q?=E9=97=AD=E5=B2=9B=E5=B1=BF=E7=9A=84=E6=95=B0=E7=9B=AE.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/1254.统计封闭岛屿的数目.md | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/problems/1254.统计封闭岛屿的数目.md b/problems/1254.统计封闭岛屿的数目.md
index 1270085a..dc8fda41 100644
--- a/problems/1254.统计封闭岛屿的数目.md
+++ b/problems/1254.统计封闭岛屿的数目.md
@@ -76,13 +76,8 @@ public:
return count;
}
};
-```
-
-
-
-
-
-### 其他语言版本
+```
+## 其他语言版本
### JavaScript:
@@ -137,3 +132,11 @@ var closedIsland = function(grid) {
return count;
};
```
+
+
+
+
+
+
+
+
From 27f8efa24c9d43b911fc7c05a7182508d50365cd Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Mon, 21 Nov 2022 23:12:33 +0800
Subject: [PATCH 44/62] =?UTF-8?q?=E5=9C=A8=E8=AE=BE=E8=AE=A1=E9=93=BE?=
=?UTF-8?q?=E8=A1=A8=E7=9A=84C++=E4=BB=A3=E7=A0=81=E9=83=A8=E5=88=86?=
=?UTF-8?q?=EF=BC=8CaddAtIndex=E6=96=B9=E6=B3=95=E4=B8=AD=EF=BC=8C?=
=?UTF-8?q?=E9=92=88=E5=AF=B9index=20<=200=20=E7=9A=84=E6=83=85=E5=86=B5?=
=?UTF-8?q?=E7=BA=A0=E9=94=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0707.设计链表.md | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md
index 1264983b..9461e263 100644
--- a/problems/0707.设计链表.md
+++ b/problems/0707.设计链表.md
@@ -108,9 +108,12 @@ public:
// 如果index大于链表的长度,则返回空
// 如果index小于0,则置为0,作为链表的新头节点。
void addAtIndex(int index, int val) {
- if (index > _size || index < 0) {
+ if (index > _size) {
return;
}
+ if (index < 0) {
+ index = 0;
+ }
LinkedNode* newNode = new LinkedNode(val);
LinkedNode* cur = _dummyHead;
while(index--) {
From cbe3bcf50a8633b2c07ff92b86b7bd9780d62848 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Tue, 22 Nov 2022 10:13:52 +0800
Subject: [PATCH 45/62] =?UTF-8?q?update=20027.=E7=A7=BB=E9=99=A4=E5=85=83?=
=?UTF-8?q?=E7=B4=A0=20python=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0027.移除元素.md | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/problems/0027.移除元素.md b/problems/0027.移除元素.md
index e1de7243..a563a13f 100644
--- a/problems/0027.移除元素.md
+++ b/problems/0027.移除元素.md
@@ -199,21 +199,15 @@ Python:
```python3
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
- if nums is None or len(nums)==0:
- return 0
- l=0
- r=len(nums)-1
- while l
Date: Tue, 22 Nov 2022 22:27:35 +0800
Subject: [PATCH 46/62] =?UTF-8?q?update=200209.=E9=95=BF=E5=BA=A6=E6=9C=80?=
=?UTF-8?q?=E5=B0=8F=E7=9A=84=E5=AD=90=E6=95=B0=E7=BB=84=20python,=20js=20?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0209.长度最小的子数组.md | 66 +++++++++++--------------------
1 file changed, 23 insertions(+), 43 deletions(-)
diff --git a/problems/0209.长度最小的子数组.md b/problems/0209.长度最小的子数组.md
index c912c259..220630f2 100644
--- a/problems/0209.长度最小的子数组.md
+++ b/problems/0209.长度最小的子数组.md
@@ -169,39 +169,18 @@ Python:
```python
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
- # 定义一个无限大的数
- res = float("inf")
- Sum = 0
- index = 0
- for i in range(len(nums)):
- Sum += nums[i]
+ res = float("inf") # 定义一个无限大的数
+ Sum = 0 # 滑动窗口数值之和
+ i = 0 # 滑动窗口起始位置
+ for j in range(len(nums)):
+ Sum += nums[j]
while Sum >= s:
- res = min(res, i-index+1)
- Sum -= nums[index]
- index += 1
- return 0 if res==float("inf") else res
-```
-```python
-# 滑动窗口
-class Solution:
- def minSubArrayLen(self, target: int, nums: List[int]) -> int:
- if nums is None or len(nums) == 0:
- return 0
- lenf = len(nums) + 1
- total = 0
- i = j = 0
- while (j < len(nums)):
- total = total + nums[j]
- j += 1
- while (total >= target):
- lenf = min(lenf, j - i)
- total = total - nums[i]
+ res = min(res, j-i+1)
+ Sum -= nums[i]
i += 1
- if lenf == len(nums) + 1:
- return 0
- else:
- return lenf
+ return 0 if res == float("inf") else res
```
+
Go:
```go
func minSubArrayLen(target int, nums []int) int {
@@ -232,22 +211,23 @@ func minSubArrayLen(target int, nums []int) int {
JavaScript:
```js
-
var minSubArrayLen = function(target, nums) {
- // 长度计算一次
- const len = nums.length;
- let l = r = sum = 0,
- res = len + 1; // 子数组最大不会超过自身
- while(r < len) {
- sum += nums[r++];
- // 窗口滑动
- while(sum >= target) {
- // r始终为开区间 [l, r)
- res = res < r - l ? res : r - l;
- sum-=nums[l++];
+ let start, end
+ start = end = 0
+ let sum = 0
+ let len = nums.length
+ let ans = Infinity
+
+ while(end < len){
+ sum += nums[end];
+ while (sum >= target) {
+ ans = Math.min(ans, end - start + 1);
+ sum -= nums[start];
+ start++;
}
+ end++;
}
- return res > len ? 0 : res;
+ return ans === Infinity ? 0 : ans
};
```
From af0e45b9af2171db2a2b5ef005745463a9d739e3 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Wed, 23 Nov 2022 23:34:26 +0800
Subject: [PATCH 47/62] =?UTF-8?q?update=200707.=E8=AE=BE=E8=AE=A1=E9=93=BE?=
=?UTF-8?q?=E8=A1=A8=20python=E4=BB=A3=E7=A0=81=EF=BC=8Cjava=E6=B3=A8?=
=?UTF-8?q?=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0707.设计链表.md | 116 +++++++++++++++++++++-----------------
1 file changed, 65 insertions(+), 51 deletions(-)
diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md
index 9461e263..f0c4bc60 100644
--- a/problems/0707.设计链表.md
+++ b/problems/0707.设计链表.md
@@ -305,7 +305,7 @@ class MyLinkedList {
head = new ListNode(0);
}
- //获取第index个节点的数值
+ //获取第index个节点的数值,注意index是从0开始的,第0个节点就是头结点
public int get(int index) {
//如果index非法,返回-1
if (index < 0 || index >= size) {
@@ -319,12 +319,12 @@ class MyLinkedList {
return currentNode.val;
}
- //在链表最前面插入一个节点
+ //在链表最前面插入一个节点,等价于在第0个元素前添加
public void addAtHead(int val) {
addAtIndex(0, val);
}
- //在链表的最后插入一个节点
+ //在链表的最后插入一个节点,等价于在(末尾+1)个元素前添加
public void addAtTail(int val) {
addAtIndex(size, val);
}
@@ -481,76 +481,90 @@ class MyLinkedList {
Python:
```python
# 单链表
-class Node:
-
- def __init__(self, val):
- self.val = val
+class Node(object):
+ def __init__(self, x=0):
+ self.val = x
self.next = None
-
-class MyLinkedList:
+class MyLinkedList(object):
def __init__(self):
- self._head = Node(0) # 虚拟头部节点
- self._count = 0 # 添加的节点数
+ self.head = Node()
+ self.size = 0 # 设置一个链表长度的属性,便于后续操作,注意每次增和删的时候都要更新
- def get(self, index: int) -> int:
+ def get(self, index):
"""
- Get the value of the index-th node in the linked list. If the index is invalid, return -1.
+ :type index: int
+ :rtype: int
"""
- if 0 <= index < self._count:
- node = self._head
- for _ in range(index + 1):
- node = node.next
- return node.val
- else:
+ if index < 0 or index >= self.size:
return -1
+ cur = self.head.next
+ while(index):
+ cur = cur.next
+ index -= 1
+ return cur.val
- def addAtHead(self, val: int) -> None:
+ def addAtHead(self, val):
"""
- Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.
+ :type val: int
+ :rtype: None
"""
- self.addAtIndex(0, val)
+ new_node = Node(val)
+ new_node.next = self.head.next
+ self.head.next = new_node
+ self.size += 1
- def addAtTail(self, val: int) -> None:
+ def addAtTail(self, val):
"""
- Append a node of value val to the last element of the linked list.
+ :type val: int
+ :rtype: None
"""
- self.addAtIndex(self._count, val)
+ new_node = Node(val)
+ cur = self.head
+ while(cur.next):
+ cur = cur.next
+ cur.next = new_node
+ self.size += 1
- def addAtIndex(self, index: int, val: int) -> None:
+ def addAtIndex(self, index, val):
"""
- Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.
+ :type index: int
+ :type val: int
+ :rtype: None
"""
if index < 0:
- index = 0
- elif index > self._count:
+ self.addAtHead(val)
+ return
+ elif index == self.size:
+ self.addAtTail(val)
+ return
+ elif index > self.size:
return
- # 计数累加
- self._count += 1
-
- add_node = Node(val)
- prev_node, current_node = None, self._head
- for _ in range(index + 1):
- prev_node, current_node = current_node, current_node.next
- else:
- prev_node.next, add_node.next = add_node, current_node
-
- def deleteAtIndex(self, index: int) -> None:
+ node = Node(val)
+ pre = self.head
+ while(index):
+ pre = pre.next
+ index -= 1
+ node.next = pre.next
+ pre.next = node
+ self.size += 1
+
+ def deleteAtIndex(self, index):
"""
- Delete the index-th node in the linked list, if the index is valid.
+ :type index: int
+ :rtype: None
"""
- if 0 <= index < self._count:
- # 计数-1
- self._count -= 1
- prev_node, current_node = None, self._head
- for _ in range(index + 1):
- prev_node, current_node = current_node, current_node.next
- else:
- prev_node.next, current_node.next = current_node.next, None
-
-
+ if index < 0 or index >= self.size:
+ return
+ pre = self.head
+ while(index):
+ pre = pre.next
+ index -= 1
+ pre.next = pre.next.next
+ self.size -= 1
+
# 双链表
# 相对于单链表, Node新增了prev属性
class Node:
From d9950cee1bb10cb826cd1522a951cbf9ceccba81 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 00:15:31 +0800
Subject: [PATCH 48/62] =?UTF-8?q?update=20=20=E9=9D=A2=E8=AF=95=E9=A2=9802?=
=?UTF-8?q?.07.=E9=93=BE=E8=A1=A8=E7=9B=B8=E4=BA=A4=20=20python=E4=BB=A3?=
=?UTF-8?q?=E7=A0=81=20js=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/面试题02.07.链表相交.md | 55 ++++++++++++++++++--------------
1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/problems/面试题02.07.链表相交.md b/problems/面试题02.07.链表相交.md
index 3277e85e..30f5c467 100644
--- a/problems/面试题02.07.链表相交.md
+++ b/problems/面试题02.07.链表相交.md
@@ -155,23 +155,28 @@ public class Solution {
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
- """
- 根据快慢法则,走的快的一定会追上走得慢的。
- 在这道题里,有的链表短,他走完了就去走另一条链表,我们可以理解为走的快的指针。
-
- 那么,只要其中一个链表走完了,就去走另一条链表的路。如果有交点,他们最终一定会在同一个
- 位置相遇
- """
- if headA is None or headB is None:
- return None
- cur_a, cur_b = headA, headB # 用两个指针代替a和b
-
-
- while cur_a != cur_b:
- cur_a = cur_a.next if cur_a else headB # 如果a走完了,那么就切换到b走
- cur_b = cur_b.next if cur_b else headA # 同理,b走完了就切换到a
-
- return cur_a
+ lenA, lenB = 0, 0
+ cur = headA
+ while cur: # 求链表A的长度
+ cur = cur.next
+ lenA += 1
+ cur = headB
+ while cur: # 求链表B的长度
+ cur = cur.next
+ lenB += 1
+ curA, curB = headA, headB
+ if lenA > lenB: # 让curB为最长链表的头,lenB为其长度
+ curA, curB = curB, curA
+ lenA, lenB = lenB, lenA
+ for _ in range(lenB - lenA): # 让curA和curB在同一起点上(末尾位置对齐)
+ curB = curB.next
+ while curA: # 遍历curA 和 curB,遇到相同则直接返回
+ if curA == curB:
+ return curA
+ else:
+ curA = curA.next
+ curB = curB.next
+ return None
```
### Go
@@ -248,19 +253,21 @@ var getListLen = function(head) {
}
var getIntersectionNode = function(headA, headB) {
let curA = headA,curB = headB,
- lenA = getListLen(headA),
- lenB = getListLen(headB);
- if(lenA < lenB) {
- // 下面交换变量注意加 “分号” ,两个数组交换变量在同一个作用域下时
+ lenA = getListLen(headA), // 求链表A的长度
+ lenB = getListLen(headB);
+ if(lenA < lenB) { // 让curA为最长链表的头,lenA为其长度
+
+ // 交换变量注意加 “分号” ,两个数组交换变量在同一个作用域下时
// 如果不加分号,下面两条代码等同于一条代码: [curA, curB] = [lenB, lenA]
+
[curA, curB] = [curB, curA];
[lenA, lenB] = [lenB, lenA];
}
- let i = lenA - lenB;
- while(i-- > 0) {
+ let i = lenA - lenB; // 求长度差
+ while(i-- > 0) { // 让curA和curB在同一起点上(末尾位置对齐)
curA = curA.next;
}
- while(curA && curA !== curB) {
+ while(curA && curA !== curB) { // 遍历curA 和 curB,遇到相同则直接返回
curA = curA.next;
curB = curB.next;
}
From e86fea0ec398e8161149377a0fc5c5480ae680d0 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 21:07:05 +0800
Subject: [PATCH 49/62] =?UTF-8?q?update=200242.=E6=9C=89=E6=95=88=E7=9A=84?=
=?UTF-8?q?=E5=AD=97=E6=AF=8D=E5=BC=82=E4=BD=8D=E8=AF=8D=EF=BC=9A=E5=8A=A0?=
=?UTF-8?q?java=E6=B3=A8=E9=87=8A=EF=BC=8C=E5=88=A0=E9=99=A4=E8=B4=A8?=
=?UTF-8?q?=E9=87=8F=E8=BE=83=E5=B7=AE=E4=B8=94=E5=A4=9A=E4=BD=99=E7=9A=84?=
=?UTF-8?q?go=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0242.有效的字母异位词.md | 35 +++++--------------------------
1 file changed, 5 insertions(+), 30 deletions(-)
diff --git a/problems/0242.有效的字母异位词.md b/problems/0242.有效的字母异位词.md
index 1281b16b..904a0527 100644
--- a/problems/0242.有效的字母异位词.md
+++ b/problems/0242.有效的字母异位词.md
@@ -101,7 +101,7 @@ class Solution {
int[] record = new int[26];
for (int i = 0; i < s.length(); i++) {
- record[s.charAt(i) - 'a']++;
+ record[s.charAt(i) - 'a']++; // 并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
}
for (int i = 0; i < t.length(); i++) {
@@ -109,11 +109,11 @@ class Solution {
}
for (int count: record) {
- if (count != 0) {
+ if (count != 0) { // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return false;
}
}
- return true;
+ return true; // record数组所有元素都为零0,说明字符串s和t是字母异位词
}
}
```
@@ -166,35 +166,10 @@ class Solution(object):
Go:
-```go
-func isAnagram(s string, t string) bool {
- if len(s)!=len(t){
- return false
- }
- exists := make(map[byte]int)
- for i:=0;i=0&&ok{
- exists[s[i]]=v+1
- }else{
- exists[s[i]]=1
- }
- }
- for i:=0;i=1&&ok{
- exists[t[i]]=v-1
- }else{
- return false
- }
- }
- return true
-}
-```
-
-Go写法二(没有使用slice作为哈希表,用数组来代替):
-
```go
func isAnagram(s string, t string) bool {
record := [26]int{}
+
for _, r := range s {
record[r-rune('a')]++
}
@@ -202,7 +177,7 @@ func isAnagram(s string, t string) bool {
record[r-rune('a')]--
}
- return record == [26]int{}
+ return record == [26]int{} // record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
}
```
From ac58e6613bd6a9d3e265e95e285c40b05bbc6f29 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 21:26:09 +0800
Subject: [PATCH 50/62] =?UTF-8?q?update=200349.=E4=B8=A4=E4=B8=AA=E6=95=B0?=
=?UTF-8?q?=E7=BB=84=E7=9A=84=E4=BA=A4=E9=9B=86=20=E4=BF=AE=E6=94=B9python?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=88=A0=E9=99=A4=E5=86=97=E4=BD=99?=
=?UTF-8?q?=E7=9A=84go=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0349.两个数组的交集.md | 32 ++++++++++++--------------------
1 file changed, 12 insertions(+), 20 deletions(-)
diff --git a/problems/0349.两个数组的交集.md b/problems/0349.两个数组的交集.md
index bd83fae9..2e98ef6f 100644
--- a/problems/0349.两个数组的交集.md
+++ b/problems/0349.两个数组的交集.md
@@ -147,32 +147,24 @@ Python3:
```python
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
- return list(set(nums1) & set(nums2)) # 两个数组先变成集合,求交集后还原为数组
+ val_dict = {}
+ ans = []
+ for num in nums1:
+ val_dict[num] = 1
+
+ for num in nums2:
+ if num in val_dict.keys() and val_dict[num] == 1:
+ ans.append(num)
+ val_dict[num] = 0
+
+ return ans
```
Go:
```go
func intersection(nums1 []int, nums2 []int) []int {
- m := make(map[int]int)
- for _, v := range nums1 {
- m[v] = 1
- }
- var res []int
- // 利用count>0,实现重复值只拿一次放入返回结果中
- for _, v := range nums2 {
- if count, ok := m[v]; ok && count > 0 {
- res = append(res, v)
- m[v]--
- }
- }
- return res
-}
-```
-```golang
-//优化版,利用set,减少count统计
-func intersection(nums1 []int, nums2 []int) []int {
- set:=make(map[int]struct{},0)
+ set:=make(map[int]struct{},0) // 用map模拟set
res:=make([]int,0)
for _,v:=range nums1{
if _,ok:=set[v];!ok{
From 4796c816421924edff6bdc2521ae0880e2d80f39 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 21:35:53 +0800
Subject: [PATCH 51/62] =?UTF-8?q?update=200001.=E4=B8=A4=E6=95=B0=E4=B9=8B?=
=?UTF-8?q?=E5=92=8C=EF=BC=9A=E5=8A=A0=E6=B3=A8=E9=87=8A=EF=BC=8C=E7=BB=99?=
=?UTF-8?q?java=E4=BB=A3=E7=A0=81=E4=B8=80=E7=82=B9=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0001.两数之和.md | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/problems/0001.两数之和.md b/problems/0001.两数之和.md
index 7bada9af..56cff527 100644
--- a/problems/0001.两数之和.md
+++ b/problems/0001.两数之和.md
@@ -134,12 +134,13 @@ public int[] twoSum(int[] nums, int target) {
}
Map map = new HashMap<>();
for(int i = 0; i < nums.length; i++){
- int temp = target - nums[i];
+ int temp = target - nums[i]; // 遍历当前元素,并在map中寻找是否有匹配的key
if(map.containsKey(temp)){
res[1] = i;
res[0] = map.get(temp);
+ break;
}
- map.put(nums[i], i);
+ map.put(nums[i], i); // 如果没找到匹配对,就把访问过的元素和下标加入到map中
}
return res;
}
@@ -152,16 +153,17 @@ class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
records = dict()
- for index, value in enumerate(nums):
- if target - value in records:
+ for index, value in enumerate(nums):
+ if target - value in records: # 遍历当前元素,并在map中寻找是否有匹配的key
return [records[target- value], index]
- records[value] = index
+ records[value] = index # 遍历当前元素,并在map中寻找是否有匹配的key
return []
```
Go:
```go
+// 暴力解法
func twoSum(nums []int, target int) []int {
for k1, _ := range nums {
for k2 := k1 + 1; k2 < len(nums); k2++ {
@@ -216,11 +218,11 @@ Javascript
```javascript
var twoSum = function (nums, target) {
let hash = {};
- for (let i = 0; i < nums.length; i++) {
+ for (let i = 0; i < nums.length; i++) { // 遍历当前元素,并在map中寻找是否有匹配的key
if (hash[target - nums[i]] !== undefined) {
return [i, hash[target - nums[i]]];
}
- hash[nums[i]] = i;
+ hash[nums[i]] = i; // 如果没找到匹配对,就把访问过的元素和下标加入到map中
}
return [];
};
From b0f84a4b357f1413118536e55f6c37c460d32674 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 21:42:38 +0800
Subject: [PATCH 52/62] =?UTF-8?q?update=200454.=E5=9B=9B=E6=95=B0=E7=9B=B8?=
=?UTF-8?q?=E5=8A=A0II=EF=BC=9A=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0454.四数相加II.md | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/problems/0454.四数相加II.md b/problems/0454.四数相加II.md
index d9fd5c04..07c3f711 100644
--- a/problems/0454.四数相加II.md
+++ b/problems/0454.四数相加II.md
@@ -168,13 +168,15 @@ Go:
```go
func fourSumCount(nums1 []int, nums2 []int, nums3 []int, nums4 []int) int {
- m := make(map[int]int)
+ m := make(map[int]int) //key:a+b的数值,value:a+b数值出现的次数
count := 0
- for _, v1 := range nums1 {
+ // 遍历nums1和nums2数组,统计两个数组元素之和,和出现的次数,放到map中
+ for _, v1 := range nums1 {
for _, v2 := range nums2 {
m[v1+v2]++
}
}
+ // 遍历nums3和nums4数组,找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来
for _, v3 := range nums3 {
for _, v4 := range nums4 {
count += m[-v3-v4]
@@ -197,14 +199,14 @@ javaScript:
var fourSumCount = function(nums1, nums2, nums3, nums4) {
const twoSumMap = new Map();
let count = 0;
-
+ // 统计nums1和nums2数组元素之和,和出现的次数,放到map中
for(const n1 of nums1) {
for(const n2 of nums2) {
const sum = n1 + n2;
twoSumMap.set(sum, (twoSumMap.get(sum) || 0) + 1)
}
}
-
+ // 找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来
for(const n3 of nums3) {
for(const n4 of nums4) {
const sum = n3 + n4;
From 983bb606d39c8ea5ab384d15d8c1bb226b65bce9 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 21:51:48 +0800
Subject: [PATCH 53/62] =?UTF-8?q?update=200383.=E8=B5=8E=E9=87=91=E4=BF=A1?=
=?UTF-8?q?:=20=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0383.赎金信.md | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/problems/0383.赎金信.md b/problems/0383.赎金信.md
index 57458308..4e6ba033 100644
--- a/problems/0383.赎金信.md
+++ b/problems/0383.赎金信.md
@@ -147,11 +147,11 @@ class Solution:
arr = [0] * 26
- for x in magazine:
+ for x in magazine: # 记录 magazine里各个字符出现次数
arr[ord(x) - ord('a')] += 1
- for x in ransomNote:
- if arr[ord(x) - ord('a')] == 0:
+ for x in ransomNote: # 在arr里对应的字符个数做--操作
+ if arr[ord(x) - ord('a')] == 0: # 如果没有出现过直接返回
return False
else:
arr[ord(x) - ord('a')] -= 1
@@ -234,12 +234,12 @@ Go:
```go
func canConstruct(ransomNote string, magazine string) bool {
record := make([]int, 26)
- for _, v := range magazine {
+ for _, v := range magazine { // 通过recode数据记录 magazine里各个字符出现次数
record[v-'a']++
}
- for _, v := range ransomNote {
+ for _, v := range ransomNote { // 遍历ransomNote,在record里对应的字符个数做--操作
record[v-'a']--
- if record[v-'a'] < 0 {
+ if record[v-'a'] < 0 { // 如果小于零说明ransomNote里出现的字符,magazine没有
return false
}
}
@@ -258,12 +258,12 @@ javaScript:
var canConstruct = function(ransomNote, magazine) {
const strArr = new Array(26).fill(0),
base = "a".charCodeAt();
- for(const s of magazine) {
+ for(const s of magazine) { // 记录 magazine里各个字符出现次数
strArr[s.charCodeAt() - base]++;
}
- for(const s of ransomNote) {
+ for(const s of ransomNote) { // 对应的字符个数做--操作
const index = s.charCodeAt() - base;
- if(!strArr[index]) return false;
+ if(!strArr[index]) return false; // 如果没记录过直接返回false
strArr[index]--;
}
return true;
From dddbb95ea718c7dfd327b270b4686a745d1e848d Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Thu, 24 Nov 2022 22:05:59 +0800
Subject: [PATCH 54/62] =?UTF-8?q?update=200015.=E4=B8=89=E6=95=B0=E4=B9=8B?=
=?UTF-8?q?=E5=92=8C=EF=BC=9A=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A=EF=BC=8C?=
=?UTF-8?q?=E4=BC=98=E5=8C=96go=E4=BB=A3=E7=A0=81=E9=A3=8E=E6=A0=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0015.三数之和.md | 56 +++++++++++++++++++++++----------------
1 file changed, 33 insertions(+), 23 deletions(-)
diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md
index 5ee57127..6675e408 100644
--- a/problems/0015.三数之和.md
+++ b/problems/0015.三数之和.md
@@ -253,13 +253,15 @@ class Solution {
public List> threeSum(int[] nums) {
List> result = new ArrayList<>();
Arrays.sort(nums);
-
+ // 找出a + b + c = 0
+ // a = nums[i], b = nums[left], c = nums[right]
for (int i = 0; i < nums.length; i++) {
- if (nums[i] > 0) {
+ // 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
+ if (nums[i] > 0) {
return result;
}
- if (i > 0 && nums[i] == nums[i - 1]) {
+ if (i > 0 && nums[i] == nums[i - 1]) { // 去重a
continue;
}
@@ -273,7 +275,7 @@ class Solution {
left++;
} else {
result.add(Arrays.asList(nums[i], nums[left], nums[right]));
-
+ // 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
@@ -294,12 +296,15 @@ class Solution:
ans = []
n = len(nums)
nums.sort()
+ # 找出a + b + c = 0
+ # a = nums[i], b = nums[left], c = nums[right]
for i in range(n):
left = i + 1
right = n - 1
- if nums[i] > 0:
+ # 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
+ if nums[i] > 0:
break
- if i >= 1 and nums[i] == nums[i - 1]:
+ if i >= 1 and nums[i] == nums[i - 1]: # 去重a
continue
while left < right:
total = nums[i] + nums[left] + nums[right]
@@ -309,13 +314,14 @@ class Solution:
left += 1
else:
ans.append([nums[i], nums[left], nums[right]])
+ # 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
while left != right and nums[left] == nums[left + 1]: left += 1
while left != right and nums[right] == nums[right - 1]: right -= 1
left += 1
right -= 1
return ans
```
-Python (v2):
+Python (v3):
```python
class Solution:
@@ -344,32 +350,36 @@ class Solution:
Go:
```Go
-func threeSum(nums []int)[][]int{
+func threeSum(nums []int) [][]int {
sort.Ints(nums)
- res:=[][]int{}
-
- for i:=0;i0{
+ res := [][]int{}
+ // 找出a + b + c = 0
+ // a = nums[i], b = nums[left], c = nums[right]
+ for i := 0; i < len(nums)-2; i++ {
+ // 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
+ n1 := nums[i]
+ if n1 > 0 {
break
}
- if i>0&&n1==nums[i-1]{
+ // 去重a
+ if i > 0 && n1 == nums[i-1] {
continue
}
- l,r:=i+1,len(nums)-1
- for l
Date: Thu, 24 Nov 2022 22:12:59 +0800
Subject: [PATCH 55/62] =?UTF-8?q?update=200018.=E5=9B=9B=E6=95=B0=E4=B9=8B?=
=?UTF-8?q?=E5=92=8C=20=E5=AE=8C=E5=96=84=E6=B3=A8=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0018.四数之和.md | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md
index ca33eb57..3fc80bba 100644
--- a/problems/0018.四数之和.md
+++ b/problems/0018.四数之和.md
@@ -136,25 +136,26 @@ class Solution {
Arrays.sort(nums);
for (int i = 0; i < nums.length; i++) {
-
+
// nums[i] > target 直接返回, 剪枝操作
if (nums[i] > 0 && nums[i] > target) {
return result;
}
-
- if (i > 0 && nums[i - 1] == nums[i]) {
+
+ if (i > 0 && nums[i - 1] == nums[i]) { // 对nums[i]去重
continue;
}
for (int j = i + 1; j < nums.length; j++) {
- if (j > i + 1 && nums[j - 1] == nums[j]) {
+ if (j > i + 1 && nums[j - 1] == nums[j]) { // 对nums[j]去重
continue;
}
int left = j + 1;
int right = nums.length - 1;
while (right > left) {
+ // nums[k] + nums[i] + nums[left] + nums[right] > target int会溢出
long sum = (long) nums[i] + nums[j] + nums[left] + nums[right];
if (sum > target) {
right--;
@@ -162,7 +163,7 @@ class Solution {
left++;
} else {
result.add(Arrays.asList(nums[i], nums[j], nums[left], nums[right]));
-
+ // 对nums[left]和nums[right]去重
while (right > left && nums[right] == nums[right - 1]) right--;
while (right > left && nums[left] == nums[left + 1]) left++;
@@ -186,10 +187,10 @@ class Solution:
nums.sort()
n = len(nums)
res = []
- for i in range(n):
- if i > 0 and nums[i] == nums[i - 1]: continue
+ for i in range(n):
+ if i > 0 and nums[i] == nums[i - 1]: continue # 对nums[i]去重
for k in range(i+1, n):
- if k > i + 1 and nums[k] == nums[k-1]: continue
+ if k > i + 1 and nums[k] == nums[k-1]: continue # 对nums[k]去重
p = k + 1
q = n - 1
@@ -198,6 +199,7 @@ class Solution:
elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1
else:
res.append([nums[i], nums[k], nums[p], nums[q]])
+ # 对nums[p]和nums[q]去重
while p < q and nums[p] == nums[p + 1]: p += 1
while p < q and nums[q] == nums[q - 1]: q -= 1
p += 1
@@ -258,12 +260,12 @@ func fourSum(nums []int, target int) [][]int {
// if n1 > target { // 不能这样写,因为可能是负数
// break
// }
- if i > 0 && n1 == nums[i-1] {
+ if i > 0 && n1 == nums[i-1] { // 对nums[i]去重
continue
}
for j := i + 1; j < len(nums)-2; j++ {
n2 := nums[j]
- if j > i+1 && n2 == nums[j-1] {
+ if j > i+1 && n2 == nums[j-1] { // 对nums[j]去重
continue
}
l := j + 1
@@ -320,6 +322,8 @@ var fourSum = function(nums, target) {
if(sum < target) { l++; continue}
if(sum > target) { r--; continue}
res.push([nums[i], nums[j], nums[l], nums[r]]);
+
+ // 对nums[left]和nums[right]去重
while(l < r && nums[l] === nums[++l]);
while(l < r && nums[r] === nums[--r]);
}
From 45dad67adf152317ae97b9c50ea82fce4fe53c31 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Fri, 25 Nov 2022 23:54:31 +0800
Subject: [PATCH 56/62] =?UTF-8?q?update=200344.=E5=8F=8D=E8=BD=AC=E5=AD=97?=
=?UTF-8?q?=E7=AC=A6=E4=B8=B2=20=E4=BC=98=E5=8C=96go=E4=BB=A3=E7=A0=81?=
=?UTF-8?q?=E6=A0=BC=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0344.反转字符串.md | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md
index 2807d04a..c4803311 100644
--- a/problems/0344.反转字符串.md
+++ b/problems/0344.反转字符串.md
@@ -190,11 +190,11 @@ class Solution:
Go:
```Go
-func reverseString(s []byte) {
- left:=0
- right:=len(s)-1
- for left
Date: Sat, 26 Nov 2022 00:07:59 +0800
Subject: [PATCH 57/62] =?UTF-8?q?update=200541.=E5=8F=8D=E8=BD=AC=E5=AD=97?=
=?UTF-8?q?=E7=AC=A6=E4=B8=B2II=EF=BC=9A=E8=A1=A5=E5=85=85=E6=B3=A8?=
=?UTF-8?q?=E9=87=8A?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0541.反转字符串II.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/problems/0541.反转字符串II.md b/problems/0541.反转字符串II.md
index 59891365..516f78da 100644
--- a/problems/0541.反转字符串II.md
+++ b/problems/0541.反转字符串II.md
@@ -294,6 +294,8 @@ func reverseStr(s string, k int) string {
ss := []byte(s)
length := len(s)
for i := 0; i < length; i += 2 * k {
+ // 1. 每隔 2k 个字符的前 k 个字符进行反转
+ // 2. 剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符
if i + k <= length {
reverse(ss[i:i+k])
} else {
@@ -326,7 +328,7 @@ javaScript:
var reverseStr = function(s, k) {
const len = s.length;
let resArr = s.split("");
- for(let i = 0; i < len; i += 2 * k) {
+ for(let i = 0; i < len; i += 2 * k) { // 每隔 2k 个字符的前 k 个字符进行反转
let l = i - 1, r = i + k > len ? len : i + k;
while(++l < --r) [resArr[l], resArr[r]] = [resArr[r], resArr[l]];
}
From e7c9a43b41af1eddb9594527bad8b7d8546eae81 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Sat, 26 Nov 2022 17:28:34 +0800
Subject: [PATCH 58/62] =?UTF-8?q?update=20=E5=89=91=E6=8C=87Offer05.?=
=?UTF-8?q?=E6=9B=BF=E6=8D=A2=E7=A9=BA=E6=A0=BC:=20=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E7=97=85=E5=8F=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/剑指Offer05.替换空格.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/problems/剑指Offer05.替换空格.md b/problems/剑指Offer05.替换空格.md
index 53f0315f..ab6eedf7 100644
--- a/problems/剑指Offer05.替换空格.md
+++ b/problems/剑指Offer05.替换空格.md
@@ -36,7 +36,7 @@ i指向新长度的末尾,j指向旧长度的末尾。
这么做有两个好处:
1. 不用申请新数组。
-2. 从后向前填充元素,避免了从前先后填充元素要来的 每次添加元素都要将添加元素之后的所有元素向后移动。
+2. 从后向前填充元素,避免了从前向后填充元素时,每次添加元素都要将添加元素之后的所有元素向后移动的问题。
时间复杂度,空间复杂度均超过100%的用户。
From 29624142179dd8f403753ede58ebcc6705684eb7 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Sat, 26 Nov 2022 17:42:51 +0800
Subject: [PATCH 59/62] =?UTF-8?q?update=200151.=E7=BF=BB=E8=BD=AC=E5=AD=97?=
=?UTF-8?q?=E7=AC=A6=E4=B8=B2=E9=87=8C=E7=9A=84=E5=8D=95=E8=AF=8D:=20?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E5=AD=97=EF=BC=8C=E4=BC=98=E5=8C=96?=
=?UTF-8?q?python=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0151.翻转字符串里的单词.md | 74 +++++++++++++++--------------
1 file changed, 38 insertions(+), 36 deletions(-)
diff --git a/problems/0151.翻转字符串里的单词.md b/problems/0151.翻转字符串里的单词.md
index 450d7258..b82204fa 100644
--- a/problems/0151.翻转字符串里的单词.md
+++ b/problems/0151.翻转字符串里的单词.md
@@ -119,7 +119,7 @@ void removeExtraSpaces(string& s) {
1. leetcode上的测试集里,字符串的长度不够长,如果足够长,性能差距会非常明显。
2. leetcode的测程序耗时不是很准确的。
-版本一的代码是比较如何一般思考过程,就是 先移除字符串钱的空格,在移除中间的,在移除后面部分。
+版本一的代码是一般的思考过程,就是 先移除字符串前的空格,再移除中间的,再移除后面部分。
不过其实还可以优化,这部分和[27.移除元素](https://programmercarl.com/0027.移除元素.html)的逻辑是一样一样的,本题是移除空格,而 27.移除元素 就是移除元素。
@@ -145,7 +145,7 @@ void removeExtraSpaces(string& s) {//去除所有空格并在相邻单词之间
此时我们已经实现了removeExtraSpaces函数来移除冗余空格。
-还做实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[344.反转字符串](https://programmercarl.com/0344.反转字符串.html)和[541.反转字符串II](https://programmercarl.com/0541.反转字符串II.html)里已经讲过了。
+还要实现反转字符串的功能,支持反转字符串子区间,这个实现我们分别在[344.反转字符串](https://programmercarl.com/0344.反转字符串.html)和[541.反转字符串II](https://programmercarl.com/0541.反转字符串II.html)里已经讲过了。
代码如下:
@@ -434,49 +434,51 @@ python:
```Python
class Solution:
#1.去除多余的空格
- def trim_spaces(self,s):
- n=len(s)
- left=0
- right=n-1
+ def trim_spaces(self, s):
+ n = len(s)
+ left = 0
+ right = n-1
- while left<=right and s[left]==' ': #去除开头的空格
- left+=1
- while left<=right and s[right]==' ': #去除结尾的空格
- right=right-1
- tmp=[]
- while left<=right: #去除单词中间多余的空格
- if s[left]!=' ':
+ while left <= right and s[left] == ' ': #去除开头的空格
+ left += 1
+ while left <= right and s[right] == ' ': #去除结尾的空格
+ right = right-1
+ tmp = []
+ while left <= right: #去除单词中间多余的空格
+ if s[left] != ' ':
tmp.append(s[left])
- elif tmp[-1]!=' ': #当前位置是空格,但是相邻的上一个位置不是空格,则该空格是合理的
+ elif tmp[-1] != ' ': #当前位置是空格,但是相邻的上一个位置不是空格,则该空格是合理的
tmp.append(s[left])
- left+=1
+ left += 1
return tmp
-#2.翻转字符数组
- def reverse_string(self,nums,left,right):
- while left
Date: Sat, 26 Nov 2022 17:50:07 +0800
Subject: [PATCH 60/62] =?UTF-8?q?update=20=E5=89=91=E6=8C=87Offer58-II.?=
=?UTF-8?q?=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=9A?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E5=AD=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/剑指Offer58-II.左旋转字符串.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md
index c34b2a71..1b619ffb 100644
--- a/problems/剑指Offer58-II.左旋转字符串.md
+++ b/problems/剑指Offer58-II.左旋转字符串.md
@@ -31,7 +31,7 @@
不能使用额外空间的话,模拟在本串操作要实现左旋转字符串的功能还是有点困难的。
-那么我们可以想一下上一题目[字符串:花式反转还不够!](https://programmercarl.com/0151.翻转字符串里的单词.html)中讲过,使用整体反转+局部反转就可以实现,反转单词顺序的目的。
+那么我们可以想一下上一题目[字符串:花式反转还不够!](https://programmercarl.com/0151.翻转字符串里的单词.html)中讲过,使用整体反转+局部反转就可以实现反转单词顺序的目的。
这道题目也非常类似,依然可以通过局部反转+整体反转 达到左旋转的目的。
@@ -41,7 +41,7 @@
2. 反转区间为n到末尾的子串
3. 反转整个字符串
-最后就可以得到左旋n的目的,而不用定义新的字符串,完全在本串上操作。
+最后就可以达到左旋n的目的,而不用定义新的字符串,完全在本串上操作。
例如 :示例1中 输入:字符串abcdefg,n=2
@@ -75,7 +75,7 @@ public:
在这篇文章[344.反转字符串](https://programmercarl.com/0344.反转字符串.html),第一次讲到反转一个字符串应该怎么做,使用了双指针法。
-然后发现[541. 反转字符串II](https://programmercarl.com/0541.反转字符串II.html),这里开始给反转加上了一些条件,当需要固定规律一段一段去处理字符串的时候,要想想在在for循环的表达式上做做文章。
+然后发现[541. 反转字符串II](https://programmercarl.com/0541.反转字符串II.html),这里开始给反转加上了一些条件,当需要固定规律一段一段去处理字符串的时候,要想想在for循环的表达式上做做文章。
后来在[151.翻转字符串里的单词](https://programmercarl.com/0151.翻转字符串里的单词.html)中,要对一句话里的单词顺序进行反转,发现先整体反转再局部反转 是一个很妙的思路。
From f95a4b6ab42d7156df54091b7d96fdf913dfd44c Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Sat, 26 Nov 2022 20:48:23 +0800
Subject: [PATCH 61/62] =?UTF-8?q?update=200028.=E5=AE=9E=E7=8E=B0strStr?=
=?UTF-8?q?=EF=BC=9A=E6=94=B9=E9=94=99=E5=AD=97=EF=BC=8C=E4=BC=98=E5=8C=96?=
=?UTF-8?q?python=E4=BB=A3=E7=A0=81=E6=A0=BC=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0028.实现strStr.md | 124 ++++++++++++++++++------------------
1 file changed, 62 insertions(+), 62 deletions(-)
diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md
index 19d16e9f..fc222441 100644
--- a/problems/0028.实现strStr.md
+++ b/problems/0028.实现strStr.md
@@ -94,7 +94,7 @@ next数组就是一个前缀表(prefix table)。
**前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。**
-为了清楚的了解前缀表的来历,我们来举一个例子:
+为了清楚地了解前缀表的来历,我们来举一个例子:
要在文本串:aabaabaafa 中查找是否出现过一个模式串:aabaaf。
@@ -110,9 +110,9 @@ next数组就是一个前缀表(prefix table)。

-动画里,我特意把 子串`aa` 标记上了,这是有原因的,大家先注意一下,后面还会说道。
+动画里,我特意把 子串`aa` 标记上了,这是有原因的,大家先注意一下,后面还会说到。
-可以看出,文本串中第六个字符b 和 模式串的第六个字符f,不匹配了。如果暴力匹配,会发现不匹配,此时就要从头匹配了。
+可以看出,文本串中第六个字符b 和 模式串的第六个字符f,不匹配了。如果暴力匹配,发现不匹配,此时就要从头匹配了。
但如果使用前缀表,就不会从头匹配,而是从上次已经匹配的内容开始匹配,找到了模式串中第三个字符b继续开始匹配。
@@ -157,7 +157,7 @@ next数组就是一个前缀表(prefix table)。
以下这句话,对于理解为什么使用前缀表可以告诉我们匹配失败之后跳到哪里重新匹配 非常重要!
-**下标5之前这部分的字符串(也就是字符串aabaa)的最长相等的前缀 和 后缀字符串是 子字符串aa ,因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面从新匹配就可以了。**
+**下标5之前这部分的字符串(也就是字符串aabaa)的最长相等的前缀 和 后缀字符串是 子字符串aa ,因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面重新匹配就可以了。**
所以前缀表具有告诉我们当前位置匹配失败,跳到之前已经匹配过的地方的能力。
@@ -199,7 +199,7 @@ next数组就是一个前缀表(prefix table)。
所以要看前一位的 前缀表的数值。
-前一个字符的前缀表的数值是2, 所有把下标移动到下标2的位置继续比配。 可以再反复看一下上面的动画。
+前一个字符的前缀表的数值是2, 所以把下标移动到下标2的位置继续比配。 可以再反复看一下上面的动画。
最后就在文本串中找到了和模式串匹配的子串了。
@@ -211,7 +211,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
为什么这么做呢,其实也是很多文章视频没有解释清楚的地方。
-其实**这并不涉及到KMP的原理,而是具体实现,next数组即可以就是前缀表,也可以是前缀表统一减一(右移一位,初始位置为-1)。**
+其实**这并不涉及到KMP的原理,而是具体实现,next数组既可以就是前缀表,也可以是前缀表统一减一(右移一位,初始位置为-1)。**
后面我会提供两种不同的实现代码,大家就明白了。
@@ -231,7 +231,7 @@ next数组就可以是前缀表,但是很多实现都是把前缀表统一减
其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。
-暴力的解法显而易见是O(n × m),所以**KMP在字符串匹配中极大的提高的搜索的效率。**
+暴力的解法显而易见是O(n × m),所以**KMP在字符串匹配中极大地提高了搜索的效率。**
为了和力扣题目28.实现strStr保持一致,方便大家理解,以下文章统称haystack为文本串, needle为模式串。
@@ -251,7 +251,7 @@ void getNext(int* next, const string& s)
2. 处理前后缀不相同的情况
3. 处理前后缀相同的情况
-接下来我们详解详解一下。
+接下来我们详解一下。
1. 初始化:
@@ -613,12 +613,12 @@ class Solution {
public void getNext(int[] next, String s){
int j = -1;
next[0] = j;
- for (int i = 1; i=0 && s.charAt(i) != s.charAt(j+1)){
+ for (int i = 1; i < s.length(); i++){
+ while(j >= 0 && s.charAt(i) != s.charAt(j+1)){
j=next[j];
}
- if(s.charAt(i)==s.charAt(j+1)){
+ if(s.charAt(i) == s.charAt(j+1)){
j++;
}
next[i] = j;
@@ -632,14 +632,14 @@ class Solution {
int[] next = new int[needle.length()];
getNext(next, needle);
int j = -1;
- for(int i = 0; i=0 && haystack.charAt(i) != needle.charAt(j+1)){
j = next[j];
}
- if(haystack.charAt(i)==needle.charAt(j+1)){
+ if(haystack.charAt(i) == needle.charAt(j+1)){
j++;
}
- if(j==needle.length()-1){
+ if(j == needle.length()-1){
return (i-needle.length()+1);
}
}
@@ -694,9 +694,9 @@ class Solution(object):
:type needle: str
:rtype: int
"""
- m,n=len(haystack),len(needle)
+ m, n = len(haystack), len(needle)
for i in range(m):
- if haystack[i:i+n]==needle:
+ if haystack[i:i+n] == needle:
return i
return -1
```
@@ -704,31 +704,31 @@ class Solution(object):
// 方法一
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
- a=len(needle)
- b=len(haystack)
- if a==0:
+ a = len(needle)
+ b = len(haystack)
+ if a == 0:
return 0
- next=self.getnext(a,needle)
+ next = self.getnext(a,needle)
p=-1
for j in range(b):
- while p>=0 and needle[p+1]!=haystack[j]:
- p=next[p]
- if needle[p+1]==haystack[j]:
- p+=1
- if p==a-1:
+ while p >= 0 and needle[p+1] != haystack[j]:
+ p = next[p]
+ if needle[p+1] == haystack[j]:
+ p += 1
+ if p == a-1:
return j-a+1
return -1
def getnext(self,a,needle):
- next=['' for i in range(a)]
- k=-1
- next[0]=k
- for i in range(1,len(needle)):
- while (k>-1 and needle[k+1]!=needle[i]):
- k=next[k]
- if needle[k+1]==needle[i]:
- k+=1
- next[i]=k
+ next = ['' for i in range(a)]
+ k = -1
+ next[0] = k
+ for i in range(1, len(needle)):
+ while (k > -1 and needle[k+1] != needle[i]):
+ k = next[k]
+ if needle[k+1] == needle[i]:
+ k += 1
+ next[i] = k
return next
```
@@ -736,34 +736,34 @@ class Solution:
// 方法二
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
- a=len(needle)
- b=len(haystack)
- if a==0:
+ a = len(needle)
+ b = len(haystack)
+ if a == 0:
return 0
- i=j=0
- next=self.getnext(a,needle)
- while(i= 0 && s[i] != s[j+1] {
- j = next[j] // 回退前一位
+ j = next[j] // 回退前一位
}
if s[i] == s[j+1] {
j++
}
- next[i] = j // next[i]是i(包括i)之前的最长相等前后缀长度
+ next[i] = j // next[i]是i(包括i)之前的最长相等前后缀长度
}
}
func strStr(haystack string, needle string) int {
@@ -796,15 +796,15 @@ func strStr(haystack string, needle string) int {
}
next := make([]int, len(needle))
getNext(next, needle)
- j := -1 // 模式串的起始位置 next为-1 因此也为-1
+ j := -1 // 模式串的起始位置 next为-1 因此也为-1
for i := 0; i < len(haystack); i++ {
for j >= 0 && haystack[i] != needle[j+1] {
- j = next[j] // 寻找下一个匹配点
+ j = next[j] // 寻找下一个匹配点
}
if haystack[i] == needle[j+1] {
j++
}
- if j == len(needle)-1 { // j指向了模式串的末尾
+ if j == len(needle)-1 { // j指向了模式串的末尾
return i - len(needle) + 1
}
}
@@ -842,7 +842,7 @@ func strStr(haystack string, needle string) int {
getNext(next, needle)
for i := 0; i < len(haystack); i++ {
for j > 0 && haystack[i] != needle[j] {
- j = next[j-1] // 回退到j的前一位
+ j = next[j-1] // 回退到j的前一位
}
if haystack[i] == needle[j] {
j++
From 7ebd52477dcd5cfeb45f700ff1b2bb2023e6b6c1 Mon Sep 17 00:00:00 2001
From: Yuhao Ju
Date: Sat, 26 Nov 2022 21:13:49 +0800
Subject: [PATCH 62/62] =?UTF-8?q?update=200459.=E9=87=8D=E5=A4=8D=E7=9A=84?=
=?UTF-8?q?=E5=AD=90=E5=AD=97=E7=AC=A6=E4=B8=B2:=E6=94=B9=E9=94=99?=
=?UTF-8?q?=E5=AD=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0459.重复的子字符串.md | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md
index b7d86880..5d870219 100644
--- a/problems/0459.重复的子字符串.md
+++ b/problems/0459.重复的子字符串.md
@@ -46,17 +46,17 @@
## 移动匹配
-当一个字符串s:abcabc,内部又重复的子串组成,那么这个字符串的结构一定是这样的:
+当一个字符串s:abcabc,内部由重复的子串组成,那么这个字符串的结构一定是这样的:

-也就是又前后又相同的子串组成。
+也就是由前后相同的子串组成。
那么既然前面有相同的子串,后面有相同的子串,用 s + s,这样组成的字符串中,后面的子串做前串,前后的子串做后串,就一定还能组成一个s,如图:

-所以判断字符串s是否有重复子串组成,只要两个s拼接在一起,里面还出现一个s的话,就说明是又重复子串组成。
+所以判断字符串s是否由重复子串组成,只要两个s拼接在一起,里面还出现一个s的话,就说明是由重复子串组成。
当然,我们在判断 s + s 拼接的字符串里是否出现一个s的的时候,**要刨除 s + s 的首字符和尾字符**,这样避免在s+s中搜索出原来的s,我们要搜索的是中间拼接出来的s。
@@ -81,7 +81,7 @@ public:
## KMP
### 为什么会使用KMP
-以下使用KMP方式讲解,强烈建议大家先把一下两个视频看了,理解KMP算法,在来看下面讲解,否则会很懵。
+以下使用KMP方式讲解,强烈建议大家先把以下两个视频看了,理解KMP算法,再来看下面讲解,否则会很懵。
* [视频讲解版:帮你把KMP算法学个通透!(理论篇)](https://www.bilibili.com/video/BV1PD4y1o7nd/)
* [视频讲解版:帮你把KMP算法学个通透!(求next数组代码篇)](https://www.bilibili.com/video/BV1M5411j7Xx)
@@ -93,12 +93,12 @@ KMP算法中next数组为什么遇到字符不匹配的时候可以找到上一
那么 最长相同前后缀和重复子串的关系又有什么关系呢。
-可能很多录友又忘了 前缀和后缀的定义,在回顾一下:
+可能很多录友又忘了 前缀和后缀的定义,再回顾一下:
* 前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串;
* 后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串
-在由重复子串组成的字符串中,最长相等前后缀不包含的子串就是最小重复子串,这里那字符串s:abababab 来举例,ab就是最小重复单位,如图所示:
+在由重复子串组成的字符串中,最长相等前后缀不包含的子串就是最小重复子串,这里拿字符串s:abababab 来举例,ab就是最小重复单位,如图所示:

@@ -123,11 +123,11 @@ KMP算法中next数组为什么遇到字符不匹配的时候可以找到上一
### 简单推理
-这里在给出一个数推导,就容易理解很多。
+这里再给出一个数学推导,就容易理解很多。
假设字符串s使用多个重复子串构成(这个子串是最小重复单位),重复出现的子字符串长度是x,所以s是由n * x组成。
-因为字符串s的最长相同前后缀的的长度一定是不包含s本身,所以 最长相同前后缀长度必然是m * x,而且 n - m = 1,(这里如果不懂,看上面的推理)
+因为字符串s的最长相同前后缀的长度一定是不包含s本身,所以 最长相同前后缀长度必然是m * x,而且 n - m = 1,(这里如果不懂,看上面的推理)
所以如果 nx % (n - m)x = 0,就可以判定有重复出现的子字符串。