Merge branch 'master' into patch-1

This commit is contained in:
程序员Carl
2023-05-08 12:54:16 +08:00
committed by GitHub
41 changed files with 1980 additions and 1174 deletions

View File

@ -151,7 +151,7 @@ public int[] twoSum(int[] nums, int target) {
``` ```
Python Python
(版本一) 使用字典
```python ```python
class Solution: class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]: def twoSum(self, nums: List[int], target: int) -> List[int]:
@ -163,6 +163,53 @@ class Solution:
records[value] = index # 遍历当前元素并在map中寻找是否有匹配的key records[value] = index # 遍历当前元素并在map中寻找是否有匹配的key
return [] return []
``` ```
(版本二)使用集合
```python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#创建一个集合来存储我们目前看到的数字
seen = set()
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [nums.index(complement), i]
seen.add(num)
```
(版本三)使用双指针
```python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
# 对输入列表进行排序
nums_sorted = sorted(nums)
# 使用双指针
left = 0
right = len(nums_sorted) - 1
while left < right:
current_sum = nums_sorted[left] + nums_sorted[right]
if current_sum == target:
# 如果和等于目标数,则返回两个数的下标
left_index = nums.index(nums_sorted[left])
right_index = nums.index(nums_sorted[right])
if left_index == right_index:
right_index = nums[left_index+1:].index(nums_sorted[right]) + left_index + 1
return [left_index, right_index]
elif current_sum < target:
# 如果总和小于目标,则将左侧指针向右移动
left += 1
else:
# 如果总和大于目标值,则将右指针向左移动
right -= 1
```
(版本四)暴力法
```python
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i+1, len(nums)):
if nums[i] + nums[j] == target:
return [i,j]
```
Go Go

View File

@ -298,61 +298,72 @@ class Solution {
``` ```
Python Python
(版本一) 双指针
```Python ```Python
class Solution: class Solution:
def threeSum(self, nums): def threeSum(self, nums: List[int]) -> List[List[int]]:
ans = [] result = []
n = len(nums)
nums.sort() nums.sort()
# 找出a + b + c = 0
# a = nums[i], b = nums[left], c = nums[right] for i in range(len(nums)):
for i in range(n): # 如果第一个元素已经大于0不需要进一步检查
left = i + 1 if nums[i] > 0:
right = n - 1 return result
# 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if nums[i] > 0: # 跳过相同的元素以避免重复
break if i > 0 and nums[i] == nums[i - 1]:
if i >= 1 and nums[i] == nums[i - 1]: # 去重a
continue continue
while left < right:
total = nums[i] + nums[left] + nums[right] left = i + 1
if total > 0: right = len(nums) - 1
right -= 1
elif total < 0: while right > left:
sum_ = nums[i] + nums[left] + nums[right]
if sum_ < 0:
left += 1 left += 1
elif sum_ > 0:
right -= 1
else: else:
ans.append([nums[i], nums[left], nums[right]]) result.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 while right > left and nums[right] == nums[right - 1]:
left += 1 right -= 1
while right > left and nums[left] == nums[left + 1]:
left += 1
right -= 1 right -= 1
return ans left += 1
return result
``` ```
Python (v3): (版本二) 使用字典
```python ```python
class Solution: class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]: def threeSum(self, nums: List[int]) -> List[List[int]]:
if len(nums) < 3: return [] result = []
nums, res = sorted(nums), [] nums.sort()
for i in range(len(nums) - 2): # 找出a + b + c = 0
cur, l, r = nums[i], i + 1, len(nums) - 1 # a = nums[i], b = nums[j], c = -(a + b)
if res != [] and res[-1][0] == cur: continue # Drop duplicates for the first time. for i in range(len(nums)):
# 排序之后如果第一个元素已经大于零,那么不可能凑成三元组
while l < r: if nums[i] > 0:
if cur + nums[l] + nums[r] == 0: break
res.append([cur, nums[l], nums[r]]) if i > 0 and nums[i] == nums[i - 1]: #三元组元素a去重
# Drop duplicates for the second time in interation of l & r. Only used when target situation occurs, because that is the reason for dropping duplicates. continue
while l < r - 1 and nums[l] == nums[l + 1]: d = {}
l += 1 for j in range(i + 1, len(nums)):
while r > l + 1 and nums[r] == nums[r - 1]: if j > i + 2 and nums[j] == nums[j-1] == nums[j-2]: # 三元组元素b去重
r -= 1 continue
if cur + nums[l] + nums[r] > 0: c = 0 - (nums[i] + nums[j])
r -= 1 if c in d:
result.append([nums[i], nums[j], c])
d.pop(c) # 三元组元素c去重
else: else:
l += 1 d[nums[j]] = j
return res return result
``` ```
Go Go

View File

@ -207,35 +207,44 @@ class Solution {
``` ```
Python Python
(版本一) 双指针
```python ```python
# 双指针法
class Solution: class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]: def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort() nums.sort()
n = len(nums) n = len(nums)
res = [] result = []
for i in range(n): for i in range(n):
if i > 0 and nums[i] == nums[i - 1]: continue # 对nums[i]去重 if nums[i] > target and nums[i] > 0 and target > 0:# 剪枝(可省)
for k in range(i+1, n): break
if k > i + 1 and nums[k] == nums[k-1]: continue # 对nums[k]去重 if i > 0 and nums[i] == nums[i-1]:# 去重
p = k + 1 continue
q = n - 1 for j in range(i+1, n):
if nums[i] + nums[j] > target and target > 0: #剪枝(可省)
while p < q: break
if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1 if j > i+1 and nums[j] == nums[j-1]: # 去重
elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1 continue
left, right = j+1, n-1
while left < right:
s = nums[i] + nums[j] + nums[left] + nums[right]
if s == target:
result.append([nums[i], nums[j], nums[left], nums[right]])
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
elif s < target:
left += 1
else: else:
res.append([nums[i], nums[k], nums[p], nums[q]]) right -= 1
# 对nums[p]和nums[q]去重 return result
while p < q and nums[p] == nums[p + 1]: p += 1
while p < q and nums[q] == nums[q - 1]: q -= 1
p += 1
q -= 1
return res
``` ```
(版本二) 使用字典
```python ```python
# 哈希表法
class Solution(object): class Solution(object):
def fourSum(self, nums, target): def fourSum(self, nums, target):
""" """
@ -243,36 +252,25 @@ class Solution(object):
:type target: int :type target: int
:rtype: List[List[int]] :rtype: List[List[int]]
""" """
# use a dict to store value:showtimes # 创建一个字典来存储输入列表中每个数字的频率
hashmap = dict() freq = {}
for n in nums: for num in nums:
if n in hashmap: freq[num] = freq.get(num, 0) + 1
hashmap[n] += 1
else:
hashmap[n] = 1
# good thing about using python is you can use set to drop duplicates. # 创建一个集合来存储最终答案并遍历4个数字的所有唯一组合
ans = set() ans = set()
# ans = [] # save results by list()
for i in range(len(nums)): for i in range(len(nums)):
for j in range(i + 1, len(nums)): for j in range(i + 1, len(nums)):
for k in range(j + 1, len(nums)): for k in range(j + 1, len(nums)):
val = target - (nums[i] + nums[j] + nums[k]) val = target - (nums[i] + nums[j] + nums[k])
if val in hashmap: if val in freq:
# make sure no duplicates. # 确保没有重复
count = (nums[i] == val) + (nums[j] == val) + (nums[k] == val) count = (nums[i] == val) + (nums[j] == val) + (nums[k] == val)
if hashmap[val] > count: if freq[val] > count:
ans_tmp = tuple(sorted([nums[i], nums[j], nums[k], val])) ans.add(tuple(sorted([nums[i], nums[j], nums[k], val])))
ans.add(ans_tmp)
# Avoiding duplication in list manner but it cause time complexity increases
# if ans_tmp not in ans:
# ans.append(ans_tmp)
else:
continue
return list(ans)
# if used list() to save results, just
# return ans
return [list(x) for x in ans]
``` ```
Go Go

View File

@ -127,21 +127,29 @@ Python:
# def __init__(self, val=0, next=None): # def __init__(self, val=0, next=None):
# self.val = val # self.val = val
# self.next = next # self.next = next
class Solution: class Solution:
def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:
head_dummy = ListNode() # 创建一个虚拟节点,并将其下一个指针设置为链表的头部
head_dummy.next = head dummy_head = ListNode(0, head)
slow, fast = head_dummy, head_dummy # 创建两个指针,慢指针和快指针,并将它们初始化为虚拟节点
while(n>=0): #fast先往前走n+1步 slow = fast = dummy_head
# 快指针比慢指针快 n+1 步
for i in range(n+1):
fast = fast.next fast = fast.next
n -= 1
while(fast!=None): # 移动两个指针,直到快速指针到达链表的末尾
while fast:
slow = slow.next slow = slow.next
fast = fast.next fast = fast.next
#fast 走到结尾后slow的下一个节点为倒数第N个节点
slow.next = slow.next.next #删除 # 通过更新第 (n-1) 个节点的 next 指针删除第 n 个节点
return head_dummy.next slow.next = slow.next.next
return dummy_head.next
``` ```
Go: Go:
```Go ```Go

View File

@ -186,21 +186,20 @@ Python
class Solution: class Solution:
def swapPairs(self, head: ListNode) -> ListNode: def swapPairs(self, head: ListNode) -> ListNode:
res = ListNode(next=head) dummy_head = ListNode(next=head)
pre = res current = dummy_head
# 必须有pre的下一个和下下个才能交换,否则说明已经交换结束了 # 必须有cur的下一个和下下个才能交换,否则说明已经交换结束了
while pre.next and pre.next.next: while current.next and current.next.next:
cur = pre.next temp = current.next # 防止节点修改
post = pre.next.next temp1 = current.next.next.next
# precurpost对应最左中间的最右边的节点 current.next = current.next.next
cur.next = post.next current.next.next = temp
post.next = cur temp.next = temp1
pre.next = post current = current.next.next
return dummy_head.next
pre = pre.next.next
return res.next
``` ```
Go Go

View File

@ -198,6 +198,7 @@ Python
``` python 3 ``` python 3
(版本一)快慢指针法
class Solution: class Solution:
def removeElement(self, nums: List[int], val: int) -> int: def removeElement(self, nums: List[int], val: int) -> int:
# 快慢指针 # 快慢指针
@ -213,7 +214,21 @@ class Solution:
return slow return slow
``` ```
``` python 3
(版本二)暴力法
class Solution:
def removeElement(self, nums: List[int], val: int) -> int:
i, l = 0, len(nums)
while i < l:
if nums[i] == val: # 找到等于目标值的节点
for j in range(i+1, l): # 移除该元素,并将后面元素向前平移
nums[j - 1] = nums[j]
l -= 1
i -= 1
i += 1
return l
```
Go Go

View File

@ -692,8 +692,67 @@ class Solution {
``` ```
Python3 Python3
(版本一)前缀表(减一)
```python
class Solution:
def getNext(self, next, s):
j = -1
next[0] = j
for i in range(1, len(s)):
while j >= 0 and s[i] != s[j+1]:
j = next[j]
if s[i] == s[j+1]:
j += 1
next[i] = j
def strStr(self, haystack: str, needle: str) -> int:
if not needle:
return 0
next = [0] * len(needle)
self.getNext(next, needle)
j = -1
for i in range(len(haystack)):
while j >= 0 and haystack[i] != needle[j+1]:
j = next[j]
if haystack[i] == needle[j+1]:
j += 1
if j == len(needle) - 1:
return i - len(needle) + 1
return -1
```
(版本二)前缀表(不减一)
```python
class Solution:
def getNext(self, next: List[int], s: str) -> None:
j = 0
next[0] = 0
for i in range(1, len(s)):
while j > 0 and s[i] != s[j]:
j = next[j - 1]
if s[i] == s[j]:
j += 1
next[i] = j
def strStr(self, haystack: str, needle: str) -> int:
if len(needle) == 0:
return 0
next = [0] * len(needle)
self.getNext(next, needle)
j = 0
for i in range(len(haystack)):
while j > 0 and haystack[i] != needle[j]:
j = next[j - 1]
if haystack[i] == needle[j]:
j += 1
if j == len(needle):
return i - len(needle) + 1
return -1
```
(版本三)暴力法
```python ```python
//暴力解法
class Solution(object): class Solution(object):
def strStr(self, haystack, needle): def strStr(self, haystack, needle):
""" """
@ -707,102 +766,22 @@ class Solution(object):
return i return i
return -1 return -1
``` ```
(版本四)使用 index
```python ```python
// 方法一
class Solution: class Solution:
def strStr(self, haystack: str, needle: str) -> int: def strStr(self, haystack: str, needle: str) -> int:
a = len(needle) try:
b = len(haystack) return haystack.index(needle)
if a == 0: except ValueError:
return 0
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:
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
return next
```
```python
// 方法二
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
a = len(needle)
b = len(haystack)
if a == 0:
return 0
i = j = 0
next = self.getnext(a, needle)
while(i < b and j < a):
if j == -1 or needle[j] == haystack[i]:
i += 1
j += 1
else:
j = next[j]
if j == a:
return i-j
else:
return -1 return -1
def getnext(self, a, needle):
next = ['' for i in range(a)]
j, k = 0, -1
next[0] = k
while(j < a-1):
if k == -1 or needle[k] == needle[j]:
k += 1
j += 1
next[j] = k
else:
k = next[k]
return next
``` ```
(版本五)使用 find
```python ```python
// 前缀表不减一Python实现
class Solution: class Solution:
def strStr(self, haystack: str, needle: str) -> int: def strStr(self, haystack: str, needle: str) -> int:
if len(needle) == 0: return haystack.find(needle)
return 0
next = self.getNext(needle) ```
j = 0
for i in range(len(haystack)):
while j >= 1 and haystack[i] != needle[j]:
j = next[j-1]
if haystack[i] == needle[j]:
j += 1
if j == len(needle):
return i - len(needle) + 1
return -1
def getNext(self, needle):
next = [0] * len(needle)
j = 0
next[0] = j
for i in range(1, len(needle)):
while j >= 1 and needle[i] != needle[j]:
j = next[j-1]
if needle[i] == needle[j]:
j += 1
next[i] = j
return next
```
Go Go

View File

@ -307,6 +307,33 @@ class Solution {
} }
} }
``` ```
单调栈精简
```java
class Solution {
public int largestRectangleArea(int[] heights) {
int[] newHeight = new int[heights.length + 2];
System.arraycopy(heights, 0, newHeight, 1, heights.length);
newHeight[heights.length+1] = 0;
newHeight[0] = 0;
Stack<Integer> stack = new Stack<>();
stack.push(0);
int res = 0;
for (int i = 1; i < newHeight.length; i++) {
while (newHeight[i] < newHeight[stack.peek()]) {
int mid = stack.pop();
int w = i - stack.peek() - 1;
int h = newHeight[mid];
res = Math.max(res, w * h);
}
stack.push(i);
}
return res;
}
}
```
Python3: Python3:

View File

@ -442,25 +442,31 @@ class Solution:
层次遍历 层次遍历
```python ```python
class Solution: class Solution:
def isSymmetric(self, root: Optional[TreeNode]) -> bool: def isSymmetric(self, root: TreeNode) -> bool:
if not root: if not root:
return True return True
que = [root] queue = collections.deque([root.left, root.right])
while que:
this_level_length = len(que) while queue:
for i in range(this_level_length // 2): level_size = len(queue)
# 要么其中一个是None但另外一个不是
if (not que[i] and que[this_level_length - 1 - i]) or (que[i] and not que[this_level_length - 1 - i]): if level_size % 2 != 0:
return False return False
# 要么两个都不是None
if que[i] and que[i].val != que[this_level_length - 1 - i].val: level_vals = []
return False for i in range(level_size):
for i in range(this_level_length): node = queue.popleft()
if not que[i]: continue if node:
que.append(que[i].left) level_vals.append(node.val)
que.append(que[i].right) queue.append(node.left)
que = que[this_level_length:] queue.append(node.right)
else:
level_vals.append(None)
if level_vals != level_vals[::-1]:
return False
return True return True
``` ```

View File

@ -171,47 +171,59 @@ python3代码
```python ```python
# 利用长度法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
"""二叉树层序遍历迭代解法""" def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
results = []
if not root: if not root:
return results return []
queue = collections.deque([root])
from collections import deque result = []
que = deque([root]) while queue:
level = []
while que: for _ in range(len(queue)):
size = len(que) cur = queue.popleft()
result = [] level.append(cur.val)
for _ in range(size):
cur = que.popleft()
result.append(cur.val)
if cur.left: if cur.left:
que.append(cur.left) queue.append(cur.left)
if cur.right: if cur.right:
que.append(cur.right) queue.append(cur.right)
results.append(result) result.append(level)
return result
return results
``` ```
```python ```python
# 递归法 # 递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]: def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
res = [] levels = []
def helper(root, depth): self.helper(root, 0, levels)
if not root: return [] return levels
if len(res) == depth: res.append([]) # start the current depth
res[depth].append(root.val) # fulfil the current depth def helper(self, node, level, levels):
if root.left: helper(root.left, depth + 1) # process child nodes for the next depth if not node:
if root.right: helper(root.right, depth + 1) return
helper(root, 0) if len(levels) == level:
return res levels.append([])
levels[level].append(node.val)
self.helper(node.left, level + 1, levels)
self.helper(node.right, level + 1, levels)
``` ```
go: go:
```go ```go
@ -500,27 +512,29 @@ python代码
class Solution: class Solution:
"""二叉树层序遍历II迭代解法""" """二叉树层序遍历II迭代解法"""
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: def levelOrderBottom(self, root: TreeNode) -> List[List[int]]:
results = []
if not root: if not root:
return results return []
queue = collections.deque([root])
from collections import deque result = []
que = deque([root]) while queue:
level = []
while que: for _ in range(len(queue)):
result = [] cur = queue.popleft()
for _ in range(len(que)): level.append(cur.val)
cur = que.popleft()
result.append(cur.val)
if cur.left: if cur.left:
que.append(cur.left) queue.append(cur.left)
if cur.right: if cur.right:
que.append(cur.right) queue.append(cur.right)
results.append(result) result.append(level)
return result[::-1]
results.reverse()
return results
``` ```
Java Java
@ -821,35 +835,35 @@ public:
python代码 python代码
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def rightSideView(self, root: TreeNode) -> List[int]: def rightSideView(self, root: TreeNode) -> List[int]:
if not root: if not root:
return [] return []
# deque来自collections模块不在力扣平台时需要手动写入 queue = collections.deque([root])
# 'from collections import deque' 导入 right_view = []
# deque相比list的好处是list的pop(0)是O(n)复杂度deque的popleft()是O(1)复杂度
while queue:
quene = deque([root]) level_size = len(queue)
out_list = []
for i in range(level_size):
while quene: node = queue.popleft()
# 每次都取最后一个node就可以了
node = quene[-1] if i == level_size - 1:
out_list.append(node.val) right_view.append(node.val)
# 执行这个遍历的目的是获取下一层所有的node
for _ in range(len(quene)):
node = quene.popleft()
if node.left: if node.left:
quene.append(node.left) queue.append(node.left)
if node.right: if node.right:
quene.append(node.right) queue.append(node.right)
return out_list return right_view
# 执行用时36 ms, 在所有 Python3 提交中击败了89.47%的用户
# 内存消耗14.6 MB, 在所有 Python3 提交中击败了96.65%的用户
``` ```
@ -1107,27 +1121,38 @@ python代码
class Solution: class Solution:
"""二叉树层平均值迭代解法""" """二叉树层平均值迭代解法"""
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def averageOfLevels(self, root: TreeNode) -> List[float]: def averageOfLevels(self, root: TreeNode) -> List[float]:
results = []
if not root: if not root:
return results return []
from collections import deque queue = collections.deque([root])
que = deque([root]) averages = []
while que: while queue:
size = len(que) size = len(queue)
sum_ = 0 level_sum = 0
for _ in range(size):
cur = que.popleft() for i in range(size):
sum_ += cur.val node = queue.popleft()
if cur.left:
que.append(cur.left)
if cur.right: level_sum += node.val
que.append(cur.right)
results.append(sum_ / size) if node.left:
queue.append(node.left)
return results if node.right:
queue.append(node.right)
averages.append(level_sum / size)
return averages
``` ```
java: java:
@ -1401,28 +1426,36 @@ public:
python代码 python代码
```python ```python
"""
# Definition for a Node.
class Node:
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Solution: class Solution:
"""N叉树的层序遍历迭代法"""
def levelOrder(self, root: 'Node') -> List[List[int]]: def levelOrder(self, root: 'Node') -> List[List[int]]:
results = []
if not root: if not root:
return results return []
from collections import deque result = []
que = deque([root]) queue = collections.deque([root])
while que: while queue:
result = [] level_size = len(queue)
for _ in range(len(que)): level = []
cur = que.popleft()
result.append(cur.val)
# cur.children 是 Node 对象组成的列表,也可能为 None
if cur.children:
que.extend(cur.children)
results.append(result)
return results for _ in range(level_size):
node = queue.popleft()
level.append(node.val)
for child in node.children:
queue.append(child)
result.append(level)
return result
``` ```
```python ```python
@ -1728,22 +1761,37 @@ public:
python代码 python代码
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def largestValues(self, root: TreeNode) -> List[int]: def largestValues(self, root: TreeNode) -> List[int]:
if root is None: if not root:
return [] return []
queue = [root]
out_list = [] result = []
queue = collections.deque([root])
while queue: while queue:
length = len(queue) level_size = len(queue)
in_list = [] max_val = float('-inf')
for _ in range(length):
curnode = queue.pop(0) for _ in range(level_size):
in_list.append(curnode.val) node = queue.popleft()
if curnode.left: queue.append(curnode.left) max_val = max(max_val, node.val)
if curnode.right: queue.append(curnode.right)
out_list.append(max(in_list)) if node.left:
return out_list queue.append(node.left)
if node.right:
queue.append(node.right)
result.append(max_val)
return result
``` ```
java代码 java代码
@ -2048,36 +2096,40 @@ class Solution {
python代码 python代码
```python ```python
# 层序遍历解法 """
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution: class Solution:
def connect(self, root: 'Node') -> 'Node': def connect(self, root: 'Node') -> 'Node':
if not root: if not root:
return None return root
queue = [root]
queue = collections.deque([root])
while queue: while queue:
n = len(queue) level_size = len(queue)
for i in range(n): prev = None
node = queue.pop(0)
for i in range(level_size):
node = queue.popleft()
if prev:
prev.next = node
prev = node
if node.left: if node.left:
queue.append(node.left) queue.append(node.left)
if node.right: if node.right:
queue.append(node.right) queue.append(node.right)
if i == n - 1:
break
node.next = queue[0]
return root
# 链表解法
class Solution:
def connect(self, root: 'Node') -> 'Node':
first = root
while first:
cur = first
while cur: # 遍历每一层的节点
if cur.left: cur.left.next = cur.right # 找左节点的next
if cur.right and cur.next: cur.right.next = cur.next.left # 找右节点的next
cur = cur.next # cur同层移动到下一节点
first = first.left # 从本层扩展到下一层
return root return root
``` ```
@ -2329,21 +2381,41 @@ python代码
```python ```python
# 层序遍历解法 # 层序遍历解法
"""
# Definition for a Node.
class Node:
def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None):
self.val = val
self.left = left
self.right = right
self.next = next
"""
class Solution: class Solution:
def connect(self, root: 'Node') -> 'Node': def connect(self, root: 'Node') -> 'Node':
if not root: if not root:
return None return root
queue = [root]
while queue: # 遍历每一层 queue = collections.deque([root])
length = len(queue)
tail = None # 每一层维护一个尾节点 while queue:
for i in range(length): # 遍历当前层 level_size = len(queue)
curnode = queue.pop(0) prev = None
if tail:
tail.next = curnode # 让尾节点指向当前节点 for i in range(level_size):
tail = curnode # 让当前节点成为尾节点 node = queue.popleft()
if curnode.left : queue.append(curnode.left)
if curnode.right: queue.append(curnode.right) if prev:
prev.next = node
prev = node
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return root return root
``` ```
@ -2592,24 +2664,31 @@ class Solution {
Python Python
```python 3 ```python 3
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def maxDepth(self, root: TreeNode) -> int: def maxDepth(self, root: TreeNode) -> int:
if root == None: if not root:
return 0 return 0
queue_ = [root]
depth = 0 depth = 0
while queue_: queue = collections.deque([root])
length = len(queue_)
for i in range(length): while queue:
cur = queue_.pop(0)
sub.append(cur.val)
#子节点入队列
if cur.left: queue_.append(cur.left)
if cur.right: queue_.append(cur.right)
depth += 1 depth += 1
for _ in range(len(queue)):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return depth return depth
``` ```
Go Go
@ -2859,23 +2938,26 @@ Python 3
# self.right = right # self.right = right
class Solution: class Solution:
def minDepth(self, root: TreeNode) -> int: def minDepth(self, root: TreeNode) -> int:
if root == None: if not root:
return 0 return 0
depth = 0
queue = collections.deque([root])
while queue:
depth += 1
for _ in range(len(queue)):
node = queue.popleft()
if not node.left and not node.right:
return depth
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
#根节点的深度为1 return depth
queue_ = [(root,1)]
while queue_:
cur, depth = queue_.pop(0)
if cur.left == None and cur.right == None:
return depth
#先左子节点,由于左子节点没有孩子,则就是这一层了
if cur.left:
queue_.append((cur.left,depth + 1))
if cur.right:
queue_.append((cur.right,depth + 1))
return 0
``` ```
Go Go

View File

@ -419,86 +419,107 @@ class solution:
return 1 + max(self.maxdepth(root.left), self.maxdepth(root.right)) return 1 + max(self.maxdepth(root.left), self.maxdepth(root.right))
``` ```
迭代法: 层序遍历迭代法:
```python ```python
import collections # Definition for a binary tree node.
class solution: # class TreeNode:
def maxdepth(self, root: treenode) -> int: # def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root: if not root:
return 0 return 0
depth = 0 #记录深度
queue = collections.deque() depth = 0
queue.append(root) queue = collections.deque([root])
while queue: while queue:
size = len(queue)
depth += 1 depth += 1
for i in range(size): for _ in range(len(queue)):
node = queue.popleft() node = queue.popleft()
if node.left: if node.left:
queue.append(node.left) queue.append(node.left)
if node.right: if node.right:
queue.append(node.right) queue.append(node.right)
return depth return depth
``` ```
### 559.n叉树的最大深度 ### 559.n叉树的最大深度
递归法: 递归法:
```python ```python
class solution: class Solution:
def maxdepth(self, root: 'node') -> int: def maxDepth(self, root: 'Node') -> int:
if not root: if not root:
return 0 return 0
depth = 0
for i in range(len(root.children)): max_depth = 1
depth = max(depth, self.maxdepth(root.children[i]))
return depth + 1 for child in root.children:
max_depth = max(max_depth, self.maxDepth(child) + 1)
return max_depth
``` ```
迭代法: 迭代法:
```python ```python
import collections """
class solution: # Definition for a Node.
def maxdepth(self, root: 'node') -> int: class Node:
queue = collections.deque() def __init__(self, val=None, children=None):
if root: self.val = val
queue.append(root) self.children = children
depth = 0 #记录深度 """
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
depth = 0
queue = collections.deque([root])
while queue: while queue:
size = len(queue)
depth += 1 depth += 1
for i in range(size): for _ in range(len(queue)):
node = queue.popleft() node = queue.popleft()
for j in range(len(node.children)): for child in node.children:
if node.children[j]: queue.append(child)
queue.append(node.children[j])
return depth return depth
``` ```
使用栈来模拟后序遍历依然可以 使用栈
```python ```python
class solution: """
def maxdepth(self, root: 'node') -> int: # Definition for a Node.
st = [] class Node:
if root: def __init__(self, val=None, children=None):
st.append(root) self.val = val
depth = 0 self.children = children
result = 0 """
while st:
node = st.pop() class Solution:
if node != none: def maxDepth(self, root: 'Node') -> int:
st.append(node) #中 if not root:
st.append(none) return 0
depth += 1
for i in range(len(node.children)): #处理孩子 max_depth = 0
if node.children[i]:
st.append(node.children[i]) stack = [(root, 1)]
else: while stack:
node = st.pop() node, depth = stack.pop()
depth -= 1 max_depth = max(max_depth, depth)
result = max(result, depth) for child in node.children:
return result stack.append((child, depth + 1))
return max_depth
``` ```

View File

@ -622,7 +622,42 @@ class Solution {
} }
} }
``` ```
```java
class Solution {
public TreeNode buildTree(int[] inorder, int[] postorder) {
if(postorder.length == 0 || inorder.length == 0)
return null;
return buildHelper(inorder, 0, inorder.length, postorder, 0, postorder.length);
}
private TreeNode buildHelper(int[] inorder, int inorderStart, int inorderEnd, int[] postorder, int postorderStart, int postorderEnd){
if(postorderStart == postorderEnd)
return null;
int rootVal = postorder[postorderEnd - 1];
TreeNode root = new TreeNode(rootVal);
int middleIndex;
for (middleIndex = inorderStart; middleIndex < inorderEnd; middleIndex++){
if(inorder[middleIndex] == rootVal)
break;
}
int leftInorderStart = inorderStart;
int leftInorderEnd = middleIndex;
int rightInorderStart = middleIndex + 1;
int rightInorderEnd = inorderEnd;
int leftPostorderStart = postorderStart;
int leftPostorderEnd = postorderStart + (middleIndex - inorderStart);
int rightPostorderStart = leftPostorderEnd;
int rightPostorderEnd = postorderEnd - 1;
root.left = buildHelper(inorder, leftInorderStart, leftInorderEnd, postorder, leftPostorderStart, leftPostorderEnd);
root.right = buildHelper(inorder, rightInorderStart, rightInorderEnd, postorder, rightPostorderStart, rightPostorderEnd);
return root;
}
}
```
105.从前序与中序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树
```java ```java

View File

@ -532,6 +532,24 @@ class Solution:
else: else:
return 1 + max(left_height, right_height) return 1 + max(left_height, right_height)
``` ```
递归法精简版:
```python
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
return self.height(root) != -1
def height(self, node: TreeNode) -> int:
if not node:
return 0
left = self.height(node.left)
if left == -1:
return -1
right = self.height(node.right)
if right == -1 or abs(left - right) > 1:
return -1
return max(left, right) + 1
```
迭代法: 迭代法:

View File

@ -305,46 +305,98 @@ class Solution {
递归法: 递归法:
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def minDepth(self, root: TreeNode) -> int: def minDepth(self, root: TreeNode) -> int:
if not root: if not root:
return 0 return 0
if not root.left and not root.right: if not root.left and not root.right:
return 1 return 1
min_depth = 10**9 left_depth = float('inf')
right_depth = float('inf')
if root.left: if root.left:
min_depth = min(self.minDepth(root.left), min_depth) # 获得左子树的最小高度 left_depth = self.minDepth(root.left)
if root.right: if root.right:
min_depth = min(self.minDepth(root.right), min_depth) # 获得右子树的最小高度 right_depth = self.minDepth(root.right)
return min_depth + 1
return 1 + min(left_depth, right_depth)
``` ```
迭代法: 迭代法:
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def minDepth(self, root: TreeNode) -> int: def minDepth(self, root: TreeNode) -> int:
if not root: if not root:
return 0 return 0
que = deque() depth = 0
que.append(root) queue = collections.deque([root])
res = 1
while queue:
while que: depth += 1
for _ in range(len(que)): for _ in range(len(queue)):
node = que.popleft() node = queue.popleft()
# 当左右孩子都为空的时候,说明是最低点的一层了,退出
if not node.left and not node.right: if not node.left and not node.right:
return res return depth
if node.left is not None:
que.append(node.left) if node.left:
if node.right is not None: queue.append(node.left)
que.append(node.right)
res += 1 if node.right:
return res queue.append(node.right)
return depth
``` ```
迭代法:
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def minDepth(self, root: TreeNode) -> int:
if not root:
return 0
queue = collections.deque([(root, 1)])
while queue:
node, depth = queue.popleft()
# Check if the node is a leaf node
if not node.left and not node.right:
return depth
# Add left and right child to the queue
if node.left:
queue.append((node.left, depth+1))
if node.right:
queue.append((node.right, depth+1))
return 0
```
## Go ## Go

View File

@ -487,140 +487,191 @@ class Solution {
### 0112.路径总和 ### 0112.路径总和
**递归** (版本一) 递归
```python ```python
class solution: # Definition for a binary tree node.
def haspathsum(self, root: treenode, targetsum: int) -> bool: # class TreeNode:
def isornot(root, targetsum) -> bool: # def __init__(self, val=0, left=None, right=None):
if (not root.left) and (not root.right) and targetsum == 0: # self.val = val
return true # 遇到叶子节点并且计数为0 # self.left = left
if (not root.left) and (not root.right): # self.right = right
return false # 遇到叶子节点计数不为0 class Solution:
if root.left: def traversal(self, cur: TreeNode, count: int) -> bool:
targetsum -= root.left.val # 左节点 if not cur.left and not cur.right and count == 0: # 遇到叶子节点并且计数为0
if isornot(root.left, targetsum): return true # 递归,处理左节点 return True
targetsum += root.left.val # 回溯 if not cur.left and not cur.right: # 遇到叶子节点直接返回
if root.right: return False
targetsum -= root.right.val # 右节点
if isornot(root.right, targetsum): return true # 递归,处理右节点 if cur.left: # 左
targetsum += root.right.val # 回溯 count -= cur.left.val
return false if self.traversal(cur.left, count): # 递归,处理节点
return True
if root == none: count += cur.left.val # 回溯,撤销处理结果
return false # 别忘记处理空treenode
else:
return isornot(root, targetsum - root.val)
class Solution: # 简洁版 if cur.right: #
def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool: count -= cur.right.val
if not root: return False if self.traversal(cur.right, count): # 递归,处理节点
if root.left==root.right==None and root.val == targetSum: return True return True
return self.hasPathSum(root.left,targetSum-root.val) or self.hasPathSum(root.right,targetSum-root.val) count += cur.right.val # 回溯,撤销处理结果
return False
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if root is None:
return False
return self.traversal(root, sum - root.val)
``` ```
**迭代 - 层序遍历** (版本二) 递归 + 精简
```python ```python
class solution: # Definition for a binary tree node.
def haspathsum(self, root: treenode, targetsum: int) -> bool: # class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root: if not root:
return false return False
if not root.left and not root.right and sum == root.val:
stack = [] # [(当前节点,路径数值), ...] return True
stack.append((root, root.val)) return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val)
while stack:
cur_node, path_sum = stack.pop()
if not cur_node.left and not cur_node.right and path_sum == targetsum:
return true
if cur_node.right:
stack.append((cur_node.right, path_sum + cur_node.right.val))
if cur_node.left:
stack.append((cur_node.left, path_sum + cur_node.left.val))
return false
``` ```
(版本三) 迭代
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def hasPathSum(self, root: TreeNode, sum: int) -> bool:
if not root:
return False
# 此时栈里要放的是pair<节点指针,路径数值>
st = [(root, root.val)]
while st:
node, path_sum = st.pop()
# 如果该节点是叶子节点了同时该节点的路径数值等于sum那么就返回true
if not node.left and not node.right and path_sum == sum:
return True
# 右节点,压进去一个节点的时候,将该节点的路径数值也记录下来
if node.right:
st.append((node.right, path_sum + node.right.val))
# 左节点,压进去一个节点的时候,将该节点的路径数值也记录下来
if node.left:
st.append((node.left, path_sum + node.left.val))
return False
```
### 0113.路径总和-ii ### 0113.路径总和-ii
**递归** (版本一) 递归
```python ```python
class solution: # Definition for a binary tree node.
def pathsum(self, root: treenode, targetsum: int) -> list[list[int]]: # class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def __init__(self):
self.result = []
self.path = []
def traversal(cur_node, remain): def traversal(self, cur, count):
if not cur_node.left and not cur_node.right: if not cur.left and not cur.right and count == 0: # 遇到了叶子节点且找到了和为sum的路径
if remain == 0: self.result.append(self.path[:])
result.append(path[:]) return
return
if cur_node.left: if not cur.left and not cur.right: # 遇到叶子节点而没有找到合适的边,直接返回
path.append(cur_node.left.val) return
traversal(cur_node.left, remain-cur_node.left.val)
path.pop()
if cur_node.right: if cur.left: # 左 (空节点不遍历)
path.append(cur_node.right.val) self.path.append(cur.left.val)
traversal(cur_node.right, remain-cur_node.right.val) count -= cur.left.val
path.pop() self.traversal(cur.left, count) # 递归
count += cur.left.val # 回溯
self.path.pop() # 回溯
result, path = [], [] if cur.right: # 右 (空节点不遍历)
self.path.append(cur.right.val)
count -= cur.right.val
self.traversal(cur.right, count) # 递归
count += cur.right.val # 回溯
self.path.pop() # 回溯
return
def pathSum(self, root: TreeNode, sum: int) -> List[List[int]]:
self.result.clear()
self.path.clear()
if not root: if not root:
return [] return self.result
path.append(root.val) self.path.append(root.val) # 把根节点放进路径
traversal(root, targetsum - root.val) self.traversal(root, sum - root.val)
return result return self.result
``` ```
**迭代法,用第二个队列保存目前的总和与路径** (版本二) 递归 + 精简
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]: def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
if not root:
return []
que, temp = deque([root]), deque([(root.val, [root.val])])
result = [] result = []
while que: self.traversal(root, targetSum, [], result)
for _ in range(len(que)):
node = que.popleft()
value, path = temp.popleft()
if (not node.left) and (not node.right):
if value == targetSum:
result.append(path)
if node.left:
que.append(node.left)
temp.append((node.left.val+value, path+[node.left.val]))
if node.right:
que.append(node.right)
temp.append((node.right.val+value, path+[node.right.val]))
return result return result
def traversal(self,node, count, path, result):
if not node:
return
path.append(node.val)
count -= node.val
if not node.left and not node.right and count == 0:
result.append(list(path))
self.traversal(node.left, count, path, result)
self.traversal(node.right, count, path, result)
path.pop()
``` ```
(版本三) 迭代
**迭代法,前序遍历**
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]: def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
if not root: return [] if not root:
stack, path_stack,result = [[root,root.val]],[[root.val]],[] return []
stack = [(root, [root.val])]
res = []
while stack: while stack:
cur,cursum = stack.pop() node, path = stack.pop()
path = path_stack.pop() if not node.left and not node.right and sum(path) == targetSum:
if cur.left==cur.right==None: res.append(path)
if cursum==targetSum: result.append(path) if node.right:
if cur.right: stack.append((node.right, path + [node.right.val]))
stack.append([cur.right,cursum+cur.right.val]) if node.left:
path_stack.append(path+[cur.right.val]) stack.append((node.left, path + [node.left.val]))
if cur.left: return res
stack.append([cur.left,cursum+cur.left.val])
path_stack.append(path+[cur.left.val])
return result
``` ```
## go ## go

View File

@ -221,25 +221,55 @@ public class Solution {
Python Python
```python ```python
版本一快慢指针法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution: class Solution:
def detectCycle(self, head: ListNode) -> ListNode: def detectCycle(self, head: ListNode) -> ListNode:
slow, fast = head, head slow = head
fast = head
while fast and fast.next: while fast and fast.next:
slow = slow.next slow = slow.next
fast = fast.next.next fast = fast.next.next
# 如果相遇
# If there is a cycle, the slow and fast pointers will eventually meet
if slow == fast: if slow == fast:
p = head # Move one of the pointers back to the start of the list
q = slow slow = head
while p!=q: while slow != fast:
p = p.next slow = slow.next
q = q.next fast = fast.next
#你也可以return q return slow
return p # If there is no cycle, return None
return None return None
``` ```
```python
版本二集合法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def detectCycle(self, head: ListNode) -> ListNode:
visited = set()
while head:
if head in visited:
return head
visited.add(head)
head = head.next
return None
```
Go Go
```go ```go

View File

@ -434,134 +434,40 @@ class Solution {
``` ```
python: python:
(版本一)先删除空白,然后整个反转,最后单词反转。
**因为字符串是不可变类型所以反转单词的时候需要将其转换成列表然后通过join函数再将其转换成列表所以空间复杂度不是O(1)**
```Python ```Python
class Solution: class Solution:
#1.去除多余的空格 def reverseWords(self, s: str) -> str:
def trim_spaces(self, s): # 删除前后空白
n = len(s) s = s.strip()
left = 0 # 反转整个字符串
right = n-1 s = s[::-1]
# 将字符串拆分为单词,并反转每个单词
while left <= right and s[left] == ' ': #去除开头的空格 s = ' '.join(word[::-1] for word in s.split())
left += 1 return s
while left <= right and s[right] == ' ': #去除结尾的空格
right -= 1
tmp = []
while left <= right: #去除单词中间多余的空格
if s[left] != ' ':
tmp.append(s[left])
elif tmp[-1] != ' ': #当前位置是空格,但是相邻的上一个位置不是空格,则该空格是合理的
tmp.append(s[left])
left += 1
return tmp
#2.翻转字符数组
def reverse_string(self, nums, left, right):
while left < right:
nums[left], nums[right] = nums[right], nums[left]
left += 1
right -= 1
return None
#3.翻转每个单词
def reverse_each_word(self, nums):
start = 0
end = 0
n = len(nums)
while start < n:
while end < n and nums[end] != ' ':
end += 1
self.reverse_string(nums, start, end-1)
start = end + 1
end += 1
return None
#4.翻转字符串里的单词
def reverseWords(self, s): #测试用例:"the sky is blue"
l = self.trim_spaces(s) #输出:['t', 'h', 'e', ' ', 's', 'k', 'y', ' ', 'i', 's', ' ', 'b', 'l', 'u', 'e'
self.reverse_string(l, 0, len(l)-1) #输出:['e', 'u', 'l', 'b', ' ', 's', 'i', ' ', 'y', 'k', 's', ' ', 'e', 'h', 't']
self.reverse_each_word(l) #输出:['b', 'l', 'u', 'e', ' ', 'i', 's', ' ', 's', 'k', 'y', ' ', 't', 'h', 'e']
return ''.join(l) #输出blue is sky the
``` ```
(版本二)使用双指针
```python ```python
class Solution: class Solution:
def reverseWords(self, s: str) -> str: def reverseWords(self, s: str) -> str:
# method 1 - Rude but work & efficient method. # 将字符串拆分为单词,即转换成列表类型
s_list = [i for i in s.split(" ") if len(i) > 0] words = s.split()
return " ".join(s_list[::-1])
# method 2 - Carlo's idea # 反转单词
def trim_head_tail_space(ss: str): left, right = 0, len(words) - 1
p = 0 while left < right:
while p < len(ss) and ss[p] == " ": words[left], words[right] = words[right], words[left]
p += 1 left += 1
return ss[p:] right -= 1
# Trim the head and tail space # 将列表转换成字符串
s = trim_head_tail_space(s) return " ".join(words)
s = trim_head_tail_space(s[::-1])[::-1]
pf, ps, s = 0, 0, s[::-1] # Reverse the string.
while pf < len(s):
if s[pf] == " ":
# Will not excede. Because we have clean the tail space.
if s[pf] == s[pf + 1]:
s = s[:pf] + s[pf + 1:]
continue
else:
s = s[:ps] + s[ps: pf][::-1] + s[pf:]
ps, pf = pf + 1, pf + 2
else:
pf += 1
return s[:ps] + s[ps:][::-1] # Must do the last step, because the last word is omit though the pointers are on the correct positions,
``` ```
```python
class Solution: # 使用双指针法移除空格
def reverseWords(self, s: str) -> str:
def removeextraspace(s):
start = 0; end = len(s)-1
while s[start]==' ':
start+=1
while s[end]==' ':
end-=1
news = list(s[start:end+1])
slow = fast = 0
while fast<len(news):
while fast>0 and news[fast]==news[fast-1]==' ':
fast+=1
news[slow]=news[fast]
slow+=1; fast+=1
#return "".join(news[:slow])
return news[:slow]
def reversestr(s):
left,right = 0,len(s)-1
news = list(s)
while left<right:
news[left],news[right] = news[right],news[left]
left+=1; right-=1
#return "".join(news)
return news
news = removeextraspace(s)
news.append(' ')
fast=slow=0
#print(news)
while fast<len(news):
while news[fast]!=' ':
fast+=1
news[slow:fast] = reversestr(news[slow:fast])
# print(news[slow:fast])
fast=slow=fast+1
news2 = reversestr(news[:-1])
return ''.join(news2)
```
Go Go
```go ```go

View File

@ -108,23 +108,14 @@ class Solution {
``` ```
Python Python
(版本一)使用集合
```python ```python
class Solution: class Solution:
def isHappy(self, n: int) -> bool: def isHappy(self, n: int) -> bool:
def calculate_happy(num):
sum_ = 0
# 从个位开始依次取,平方求和
while num:
sum_ += (num % 10) ** 2
num = num // 10
return sum_
# 记录中间结果
record = set() record = set()
while True: while True:
n = calculate_happy(n) n = self.get_sum(n)
if n == 1: if n == 1:
return True return True
@ -134,21 +125,86 @@ class Solution:
else: else:
record.add(n) record.add(n)
# python的另一种写法 - 通过字符串来计算各位平方和 def get_sum(self,n: int) -> int:
new_num = 0
while n:
n, r = divmod(n, 10)
new_num += r ** 2
return new_num
```
(版本二)使用集合
```python
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
while n not in record:
record.add(n)
new_num = 0
n_str = str(n)
for i in n_str:
new_num+=int(i)**2
if new_num==1: return True
else: n = new_num
return False
```
(版本三)使用数组
```python
class Solution: class Solution:
def isHappy(self, n: int) -> bool: def isHappy(self, n: int) -> bool:
record = [] record = []
while n not in record: while n not in record:
record.append(n) record.append(n)
newn = 0 new_num = 0
nn = str(n) n_str = str(n)
for i in nn: for i in n_str:
newn+=int(i)**2 new_num+=int(i)**2
if newn==1: return True if new_num==1: return True
n = newn else: n = new_num
return False return False
``` ```
(版本四)使用快慢指针
```python
class Solution:
def isHappy(self, n: int) -> bool:
slow = n
fast = n
while self.get_sum(fast) != 1 and self.get_sum(self.get_sum(fast)):
slow = self.get_sum(slow)
fast = self.get_sum(self.get_sum(fast))
if slow == fast:
return False
return True
def get_sum(self,n: int) -> int:
new_num = 0
while n:
n, r = divmod(n, 10)
new_num += r ** 2
return new_num
```
(版本五)使用集合+精简
```python
class Solution:
def isHappy(self, n: int) -> bool:
seen = set()
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in seen:
return False
seen.add(n)
return True
```
(版本六)使用数组+精简
```python
class Solution:
def isHappy(self, n: int) -> bool:
seen = []
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in seen:
return False
seen.append(n)
return True
```
Go Go
```go ```go
func isHappy(n int) bool { func isHappy(n int) bool {

View File

@ -307,21 +307,27 @@ public ListNode removeElements(ListNode head, int val) {
Python Python
```python ```python
版本一虚拟头节点法
# Definition for singly-linked list. # Definition for singly-linked list.
# class ListNode: # class ListNode:
# def __init__(self, val=0, next=None): # def __init__(self, val=0, next=None):
# self.val = val # self.val = val
# self.next = next # self.next = next
class Solution: class Solution:
def removeElements(self, head: ListNode, val: int) -> ListNode: def removeElements(self, head: Optional[ListNode], val: int) -> Optional[ListNode]:
dummy_head = ListNode(next=head) #添加一个虚拟节点 # 创建虚拟头部节点以简化删除过程
cur = dummy_head dummy_head = ListNode(next = head)
while cur.next:
if cur.next.val == val: # 遍历列表并删除值为val的节点
cur.next = cur.next.next #删除cur.next节点 current = dummy_head
while current.next:
if current.next.val == val:
current.next = current.next.next
else: else:
cur = cur.next current = current.next
return dummy_head.next return dummy_head.next
``` ```
Go Go

View File

@ -193,9 +193,9 @@ class Solution {
} }
``` ```
Python迭代法: Python
```python ```python
#双指针 版本一双指针
# Definition for singly-linked list. # Definition for singly-linked list.
# class ListNode: # class ListNode:
# def __init__(self, val=0, next=None): # def __init__(self, val=0, next=None):
@ -205,7 +205,7 @@ class Solution:
def reverseList(self, head: ListNode) -> ListNode: def reverseList(self, head: ListNode) -> ListNode:
cur = head cur = head
pre = None pre = None
while(cur!=None): while cur:
temp = cur.next # 保存一下 cur的下一个节点因为接下来要改变cur->next temp = cur.next # 保存一下 cur的下一个节点因为接下来要改变cur->next
cur.next = pre #反转 cur.next = pre #反转
#更新pre、cur指针 #更新pre、cur指针
@ -217,6 +217,7 @@ class Solution:
Python递归法 Python递归法
```python ```python
版本二递归法
# Definition for singly-linked list. # Definition for singly-linked list.
# class ListNode: # class ListNode:
# def __init__(self, val=0, next=None): # def __init__(self, val=0, next=None):
@ -224,36 +225,17 @@ Python递归法
# self.next = next # self.next = next
class Solution: class Solution:
def reverseList(self, head: ListNode) -> ListNode: def reverseList(self, head: ListNode) -> ListNode:
return self.reverse(head, None)
def reverse(pre,cur): def reverse(self, cur: ListNode, pre: ListNode) -> ListNode:
if not cur: if cur == None:
return pre return pre
temp = cur.next
tmp = cur.next cur.next = pre
cur.next = pre return self.reverse(temp, cur)
return reverse(cur,tmp)
return reverse(None,head)
``` ```
Python递归法从后向前
```python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
if not head or not head.next: return head
p = self.reverseList(head.next)
head.next.next = head
head.next = None
return p
```
Go Go

View File

@ -173,18 +173,44 @@ class Solution {
Python Python
```python ```python
版本一滑动窗口法
class Solution: class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int: def minSubArrayLen(self, s: int, nums: List[int]) -> int:
res = float("inf") # 定义一个无限大的数 l = len(nums)
Sum = 0 # 滑动窗口数值之和 left = 0
i = 0 # 滑动窗口起始位置 right = 0
for j in range(len(nums)): min_len = float('inf')
Sum += nums[j] cur_sum = 0 #当前的累加值
while Sum >= s:
res = min(res, j-i+1) while right < l:
Sum -= nums[i] cur_sum += nums[right]
i += 1
return 0 if res == float("inf") else res while cur_sum >= s: # 当前累加值大于目标值
min_len = min(min_len, right - left + 1)
cur_sum -= nums[left]
left += 1
right += 1
return min_len if min_len != float('inf') else 0
```
```python
版本二暴力法
class Solution:
def minSubArrayLen(self, s: int, nums: List[int]) -> int:
l = len(nums)
min_len = float('inf')
for i in range(l):
cur_sum = 0
for j in range(i, l):
cur_sum += nums[j]
if cur_sum >= s:
min_len = min(min_len, j - i + 1)
break
return min_len if min_len != float('inf') else 0
``` ```
Go Go

View File

@ -393,6 +393,20 @@ class Solution: # 利用完全二叉树特性
return 2**count-1 return 2**count-1
return 1+self.countNodes(root.left)+self.countNodes(root.right) return 1+self.countNodes(root.left)+self.countNodes(root.right)
``` ```
完全二叉树写法3
```python
class Solution: # 利用完全二叉树特性
def countNodes(self, root: TreeNode) -> int:
if not root: return 0
count = 0
left = root.left; right = root.right
while left and right:
count+=1
left = left.left; right = right.right
if not left and not right: # 如果同时到底说明是满二叉树,反之则不是
return (2<<count)-1
return 1+self.countNodes(root.left)+self.countNodes(root.right)
```
## Go ## Go

View File

@ -314,81 +314,158 @@ class Solution {
递归法:前序遍历: 递归法:前序遍历:
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def invertTree(self, root: TreeNode) -> TreeNode: def invertTree(self, root: TreeNode) -> TreeNode:
if not root: if not root:
return None return None
root.left, root.right = root.right, root.left #中 root.left, root.right = root.right, root.left
self.invertTree(root.left) #左 self.invertTree(root.left)
self.invertTree(root.right) #右 self.invertTree(root.right)
return root return root
``` ```
递归法:序遍历: 迭代法:序遍历:
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def invertTree(self, root: TreeNode) -> TreeNode: def invertTree(self, root: TreeNode) -> TreeNode:
if root is None: if not root:
return None
stack = [root]
while stack:
node = stack.pop()
node.left, node.right = node.right, node.left
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return root
```
递归法:中序遍历:
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
self.invertTree(root.left)
root.left, root.right = root.right, root.left
self.invertTree(root.left)
return root
```
迭代法:中序遍历:
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None
stack = [root]
while stack:
node = stack.pop()
if node.left:
stack.append(node.left)
node.left, node.right = node.right, node.left
if node.left:
stack.append(node.left)
return root
```
递归法:后序遍历:
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return None return None
self.invertTree(root.left) self.invertTree(root.left)
self.invertTree(root.right) self.invertTree(root.right)
root.left, root.right = root.right, root.left root.left, root.right = root.right, root.left
return root return root
``` ```
迭代法:深度优先遍历(前序遍历 迭代法:序遍历:
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def invertTree(self, root: TreeNode) -> TreeNode: def invertTree(self, root: TreeNode) -> TreeNode:
if not root: if not root:
return root return None
st = [] stack = [root]
st.append(root) while stack:
while st: node = stack.pop()
node = st.pop()
node.left, node.right = node.right, node.left #中
if node.right:
st.append(node.right) #右
if node.left: if node.left:
st.append(node.left) #左 stack.append(node.left)
if node.right:
stack.append(node.right)
node.left, node.right = node.right, node.left
return root return root
``` ```
迭代法:广度优先遍历(层序遍历): 迭代法:广度优先遍历(层序遍历):
```python ```python
import collections # Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def invertTree(self, root: TreeNode) -> TreeNode: def invertTree(self, root: TreeNode) -> TreeNode:
queue = collections.deque() #使用deque() if not root:
if root: return None
queue.append(root)
queue = collections.deque([root])
while queue: while queue:
size = len(queue) for i in range(len(queue)):
for i in range(size):
node = queue.popleft() node = queue.popleft()
node.left, node.right = node.right, node.left #节点处理 node.left, node.right = node.right, node.left
if node.left: if node.left: queue.append(node.left)
queue.append(node.left) if node.right: queue.append(node.right)
if node.right:
queue.append(node.right)
return root
```
迭代法:广度优先遍历(层序遍历),和之前的层序遍历写法一致:
```python
class Solution:
def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
if not root: return root
from collections import deque
que=deque([root])
while que:
size=len(que)
for i in range(size):
cur=que.popleft()
cur.left, cur.right = cur.right, cur.left
if cur.left: que.append(cur.left)
if cur.right: que.append(cur.right)
return root return root
``` ```
### Go ### Go
递归版本的前序遍历 递归版本的前序遍历

View File

@ -122,6 +122,7 @@ class Solution {
``` ```
Python Python
```python ```python
class Solution: class Solution:
def isAnagram(self, s: str, t: str) -> bool: def isAnagram(self, s: str, t: str) -> bool:
@ -137,7 +138,6 @@ class Solution:
return False return False
return True return True
``` ```
Python写法二没有使用数组作为哈希表只是介绍defaultdict这样一种解题思路 Python写法二没有使用数组作为哈希表只是介绍defaultdict这样一种解题思路
```python ```python
@ -147,13 +147,11 @@ class Solution:
s_dict = defaultdict(int) s_dict = defaultdict(int)
t_dict = defaultdict(int) t_dict = defaultdict(int)
for x in s: for x in s:
s_dict[x] += 1 s_dict[x] += 1
for x in t: for x in t:
t_dict[x] += 1 t_dict[x] += 1
return s_dict == t_dict return s_dict == t_dict
``` ```
Python写法三(没有使用数组作为哈希表只是介绍Counter这种更方便的解题思路) Python写法三(没有使用数组作为哈希表只是介绍Counter这种更方便的解题思路)
@ -165,7 +163,6 @@ class Solution(object):
a_count = Counter(s) a_count = Counter(s)
b_count = Counter(t) b_count = Counter(t)
return a_count == b_count return a_count == b_count
```
Go Go

View File

@ -468,6 +468,71 @@ class Solution {
``` ```
--- ---
## Python: ## Python:
递归法+回溯(版本一)
```Python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
import copy
from typing import List, Optional
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
if not root:
return []
result = []
self.generate_paths(root, [], result)
return result
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None:
path.append(node.val)
if not node.left and not node.right:
result.append('->'.join(map(str, path)))
if node.left:
self.generate_paths(node.left, copy.copy(path), result)
if node.right:
self.generate_paths(node.right, copy.copy(path), result)
path.pop()
```
递归法+回溯(版本二)
```Python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
import copy
from typing import List, Optional
class Solution:
def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
if not root:
return []
result = []
self.generate_paths(root, [], result)
return result
def generate_paths(self, node: TreeNode, path: List[int], result: List[str]) -> None:
if not node:
return
path.append(node.val)
if not node.left and not node.right:
result.append('->'.join(map(str, path)))
else:
self.generate_paths(node.left, copy.copy(path), result)
self.generate_paths(node.right, copy.copy(path), result)
path.pop()
```
递归法+隐形回溯 递归法+隐形回溯
```Python ```Python
# Definition for a binary tree node. # Definition for a binary tree node.

View File

@ -174,6 +174,7 @@ class Solution {
``` ```
Python Python
(版本一) 双指针
```python ```python
class Solution: class Solution:
def reverseString(self, s: List[str]) -> None: def reverseString(self, s: List[str]) -> None:
@ -182,15 +183,70 @@ class Solution:
""" """
left, right = 0, len(s) - 1 left, right = 0, len(s) - 1
# 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(right//2)更低 # 该方法已经不需要判断奇偶数,经测试后时间空间复杂度比用 for i in range(len(s)//2)更低
# 推荐该写法,更加通俗易懂 # 因为while每次循环需要进行条件判断而range函数不需要直接生成数字因此时间复杂度更低。推荐使用range
while left < right: while left < right:
s[left], s[right] = s[right], s[left] s[left], s[right] = s[right], s[left]
left += 1 left += 1
right -= 1 right -= 1
``` ```
(版本二) 使用栈
```python
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
stack = []
for char in s:
stack.append(char)
for i in range(len(s)):
s[i] = stack.pop()
```
(版本三) 使用range
```python
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
n = len(s)
for i in range(n // 2):
s[i], s[n - i - 1] = s[n - i - 1], s[i]
```
(版本四) 使用reversed
```python
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = reversed(s)
```
(版本五) 使用切片
```python
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = s[::-1]
```
(版本六) 使用列表推导
```python
class Solution:
def reverseString(self, s: List[str]) -> None:
"""
Do not return anything, modify s in-place instead.
"""
s[:] = [s[i] for i in range(len(s) - 1, -1, -1)]
```
Go Go
```Go ```Go
func reverseString(s []byte) { func reverseString(s []byte) {

View File

@ -160,22 +160,29 @@ class Solution {
``` ```
Python3 Python3
(版本一) 使用字典和集合
```python ```python
class Solution: class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]: def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
val_dict = {} # 使用哈希表存储一个数组中的所有元素
ans = [] table = {}
for num in nums1: for num in nums1:
val_dict[num] = 1 table[num] = table.get(num, 0) + 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 # 使用集合存储结果
res = set()
for num in nums2:
if num in table:
res.add(num)
del table[num]
return list(res)
```
(版本二) 使用数组
```python
class Solution: # 使用数组方法 class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]: def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
count1 = [0]*1001 count1 = [0]*1001
count2 = [0]*1001 count2 = [0]*1001
@ -190,7 +197,14 @@ class Solution: # 使用数组方法
return result return result
``` ```
(版本三) 使用集合
```python
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
```
Go Go
```go ```go

View File

@ -146,34 +146,27 @@ class Solution {
``` ```
Python写法一使用数组作为哈希表 (版本一)使用数组
```python ```python
class Solution: class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool: def canConstruct(self, ransomNote: str, magazine: str) -> bool:
ransom_count = [0] * 26
arr = [0] * 26 magazine_count = [0] * 26
for c in ransomNote:
for x in magazine: # 记录 magazine里各个字符出现次数 ransom_count[ord(c) - ord('a')] += 1
arr[ord(x) - ord('a')] += 1 for c in magazine:
magazine_count[ord(c) - ord('a')] += 1
for x in ransomNote: # 在arr里对应的字符个数做--操作 return all(ransom_count[i] <= magazine_count[i] for i in range(26))
if arr[ord(x) - ord('a')] == 0: # 如果没有出现过直接返回
return False
else:
arr[ord(x) - ord('a')] -= 1
return True
``` ```
Python写法二使用defaultdict 版本二)使用defaultdict
```python ```python
from collections import defaultdict
class Solution: class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool: def canConstruct(self, ransomNote: str, magazine: str) -> bool:
from collections import defaultdict
hashmap = defaultdict(int) hashmap = defaultdict(int)
for x in magazine: for x in magazine:
@ -181,59 +174,43 @@ class Solution:
for x in ransomNote: for x in ransomNote:
value = hashmap.get(x) value = hashmap.get(x)
if value is None or value == 0: if not value or not value:
return False return False
else: else:
hashmap[x] -= 1 hashmap[x] -= 1
return True return True
``` ```
(版本三)使用字典
Python写法三
```python
class Solution(object):
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
# use a dict to store the number of letter occurance in ransomNote
hashmap = dict()
for s in ransomNote:
if s in hashmap:
hashmap[s] += 1
else:
hashmap[s] = 1
# check if the letter we need can be found in magazine
for l in magazine:
if l in hashmap:
hashmap[l] -= 1
for key in hashmap:
if hashmap[key] > 0:
return False
return True
```
Python写法四
```python ```python
class Solution: class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool: def canConstruct(self, ransomNote: str, magazine: str) -> bool:
c1 = collections.Counter(ransomNote) counts = {}
c2 = collections.Counter(magazine) for c in magazine:
x = c1 - c2 counts[c] = counts.get(c, 0) + 1
#x只保留值大于0的符号当c1里面的符号个数小于c2时不会被保留 for c in ransomNote:
#所以x只保留下了magazine不能表达的 if c not in counts or counts[c] == 0:
if(len(x)==0): return False
return True counts[c] -= 1
else: return True
return False ```
版本四使用Counter
```python
from collections import Counter
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
return not Counter(ransomNote) - Counter(magazine)
```
版本五使用count
```python
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
return all(ransomNote.count(c) <= magazine.count(c) for c in set(ransomNote))
``` ```
Go Go

View File

@ -250,19 +250,27 @@ class Solution {
**递归后序遍历** **递归后序遍历**
```python ```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int: def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
if not root: if not root:
return 0 return 0
left_left_leaves_sum = self.sumOfLeftLeaves(root.left) # 左 # 检查根节点的左子节点是否为叶节点
right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右 if root.left and not root.left.left and not root.left.right:
left_val = root.left.val
cur_left_leaf_val = 0 else:
if root.left and not root.left.left and not root.left.right: left_val = self.sumOfLeftLeaves(root.left)
cur_left_leaf_val = root.left.val
return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum # 中 # 递归地计算右子树左叶节点的和
right_val = self.sumOfLeftLeaves(root.right)
return left_val + right_val
``` ```
**迭代** **迭代**

View File

@ -118,11 +118,11 @@ class Solution {
``` ```
Python Python
(版本一) 使用字典
```python ```python
class Solution(object): class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4): def fourSumCount(self, nums1, nums2, nums3, nums4):
# use a dict to store the elements in nums1 and nums2 and their sum # 使用字典存储nums1和nums2中的元素及其和
hashmap = dict() hashmap = dict()
for n1 in nums1: for n1 in nums1:
for n2 in nums2: for n2 in nums2:
@ -131,7 +131,7 @@ class Solution(object):
else: else:
hashmap[n1+n2] = 1 hashmap[n1+n2] = 1
# if the -(a+b) exists in nums3 and nums4, we shall add the count # 如果 -(n1+n2) 存在于nums3和nums4, 存入结果
count = 0 count = 0
for n3 in nums3: for n3 in nums3:
for n4 in nums4: for n4 in nums4:
@ -142,20 +142,40 @@ class Solution(object):
``` ```
(版本二) 使用字典
```python ```python
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
# 使用字典存储nums1和nums2中的元素及其和
hashmap = dict()
for n1 in nums1:
for n2 in nums2:
hashmap[n1+n2] = hashmap.get(n1+n2, 0) + 1
# 如果 -(n1+n2) 存在于nums3和nums4, 存入结果
count = 0
for n3 in nums3:
for n4 in nums4:
key = - n3 - n4
if key in hashmap:
count += hashmap[key]
return count
```
(版本三)使用 defaultdict
```python
from collections import defaultdict
class Solution: class Solution:
def fourSumCount(self, nums1: list, nums2: list, nums3: list, nums4: list) -> int: def fourSumCount(self, nums1: list, nums2: list, nums3: list, nums4: list) -> int:
from collections import defaultdict # You may use normal dict instead.
rec, cnt = defaultdict(lambda : 0), 0 rec, cnt = defaultdict(lambda : 0), 0
# To store the summary of all the possible combinations of nums1 & nums2, together with their frequencies.
for i in nums1: for i in nums1:
for j in nums2: for j in nums2:
rec[i+j] += 1 rec[i+j] += 1
# To add up the frequencies if the corresponding value occurs in the dictionary
for i in nums3: for i in nums3:
for j in nums4: for j in nums4:
cnt += rec.get(-(i+j), 0) # No matched key, return 0. cnt += rec.get(-(i+j), 0)
return cnt return cnt
``` ```

View File

@ -264,8 +264,7 @@ class Solution {
Python Python
这里使用了前缀表统一减一的实现方式 (版本一) 前缀表 减一
```python ```python
class Solution: class Solution:
def repeatedSubstringPattern(self, s: str) -> bool: def repeatedSubstringPattern(self, s: str) -> bool:
@ -289,7 +288,7 @@ class Solution:
return nxt return nxt
``` ```
前缀表不减一)的代码实现 (版本二) 前缀表 不减一
```python ```python
class Solution: class Solution:
@ -314,6 +313,40 @@ class Solution:
return nxt return nxt
``` ```
(版本三) 使用 find
```python
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
n = len(s)
if n <= 1:
return False
ss = s[1:] + s[:-1]
print(ss.find(s))
return ss.find(s) != -1
```
(版本四) 暴力法
```python
class Solution:
def repeatedSubstringPattern(self, s: str) -> bool:
n = len(s)
if n <= 1:
return False
substr = ""
for i in range(1, n//2 + 1):
if n % i == 0:
substr = s[:i]
if substr * (n//i) == s:
return True
return False
```
Go Go
这里使用了前缀表统一减一的实现方式 这里使用了前缀表统一减一的实现方式

View File

@ -271,52 +271,80 @@ class Solution {
### Python ### Python
(版本一)递归法 + 回溯
递归:
```python ```python
class Solution: class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int: def findBottomLeftValue(self, root: TreeNode) -> int:
max_depth = -float("INF") self.max_depth = float('-inf')
leftmost_val = 0 self.result = None
self.traversal(root, 0)
return self.result
def traversal(self, node, depth):
if not node.left and not node.right:
if depth > self.max_depth:
self.max_depth = depth
self.result = node.val
return
if node.left:
depth += 1
self.traversal(node.left, depth)
depth -= 1
if node.right:
depth += 1
self.traversal(node.right, depth)
depth -= 1
def __traverse(root, cur_depth):
nonlocal max_depth, leftmost_val
if not root.left and not root.right:
if cur_depth > max_depth:
max_depth = cur_depth
leftmost_val = root.val
if root.left:
cur_depth += 1
__traverse(root.left, cur_depth)
cur_depth -= 1
if root.right:
cur_depth += 1
__traverse(root.right, cur_depth)
cur_depth -= 1
__traverse(root, 0)
return leftmost_val
``` ```
迭代 - 层序遍历: (版本二)递归法+精简
```python ```python
class Solution: class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int: def findBottomLeftValue(self, root: TreeNode) -> int:
queue = deque() self.max_depth = float('-inf')
if root: self.result = None
queue.append(root) self.traversal(root, 0)
result = 0 return self.result
while queue:
q_len = len(queue) def traversal(self, node, depth):
for i in range(q_len): if not node.left and not node.right:
if i == 0: if depth > self.max_depth:
result = queue[i].val self.max_depth = depth
cur = queue.popleft() self.result = node.val
if cur.left: return
queue.append(cur.left)
if cur.right: if node.left:
queue.append(cur.right) self.traversal(node.left, depth+1)
return result if node.right:
self.traversal(node.right, depth+1)
```
(版本三) 迭代法
```python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
from collections import deque
class Solution:
def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
queue = deque([root])
while queue:
size = len(queue)
leftmost = queue[0].val
for i in range(size):
node = queue.popleft()
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
if not queue:
return leftmost
``` ```
### Go ### Go

View File

@ -267,6 +267,27 @@ class Solution {
return ans; return ans;
} }
} }
```
动态规划:简洁版
```java
class Solution {
public int countSubstrings(String s) {
boolean[][] dp = new boolean[s.length()][s.length()];
int res = 0;
for (int i = s.length() - 1; i >= 0; i--) {
for (int j = i; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j) && (j - i <= 1 || dp[i + 1][j - 1])) {
res++;
dp[i][j] = true;
}
}
}
return res;
}
}
``` ```
中心扩散法: 中心扩散法:

View File

@ -485,177 +485,176 @@ class MyLinkedList {
Python Python
```python ```python
# 单链表 版本一单链表
class Node(object): class ListNode:
def __init__(self, x=0): def __init__(self, val=0, next=None):
self.val = x
self.next = None
class MyLinkedList(object):
def __init__(self):
self.head = Node()
self.size = 0 # 设置一个链表长度的属性,便于后续操作,注意每次增和删的时候都要更新
def get(self, index):
"""
:type index: int
:rtype: int
"""
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):
"""
:type val: int
:rtype: None
"""
new_node = Node(val)
new_node.next = self.head.next
self.head.next = new_node
self.size += 1
def addAtTail(self, val):
"""
:type val: int
:rtype: None
"""
new_node = Node(val)
cur = self.head
while(cur.next):
cur = cur.next
cur.next = new_node
self.size += 1
def addAtIndex(self, index, val):
"""
:type index: int
:type val: int
:rtype: None
"""
if index < 0:
self.addAtHead(val)
return
elif index == self.size:
self.addAtTail(val)
return
elif index > self.size:
return
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):
"""
:type index: int
:rtype: 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:
def __init__(self, val):
self.val = val self.val = val
self.prev = None self.next = next
self.next = None
class MyLinkedList: class MyLinkedList:
def __init__(self): def __init__(self):
self._head, self._tail = Node(0), Node(0) # 虚拟节点 self.dummy_head = ListNode()
self._head.next, self._tail.prev = self._tail, self._head self.size = 0
self._count = 0 # 添加的节点数
def _get_node(self, index: int) -> Node:
# 当index小于_count//2时, 使用_head查找更快, 反之_tail更快
if index >= self._count // 2:
# 使用prev往前找
node = self._tail
for _ in range(self._count - index):
node = node.prev
else:
# 使用next往后找
node = self._head
for _ in range(index + 1):
node = node.next
return node
def get(self, index: int) -> int: def get(self, index: int) -> int:
""" if index < 0 or index >= self.size:
Get the value of the index-th node in the linked list. If the index is invalid, return -1.
"""
if 0 <= index < self._count:
node = self._get_node(index)
return node.val
else:
return -1 return -1
current = self.dummy_head.next
for i in range(index):
current = current.next
return current.val
def addAtHead(self, val: int) -> None: def addAtHead(self, val: int) -> None:
""" self.dummy_head.next = ListNode(val, self.dummy_head.next)
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. self.size += 1
"""
self._update(self._head, self._head.next, val)
def addAtTail(self, val: int) -> None: def addAtTail(self, val: int) -> None:
""" current = self.dummy_head
Append a node of value val to the last element of the linked list. while current.next:
""" current = current.next
self._update(self._tail.prev, self._tail, val) current.next = ListNode(val)
self.size += 1
def addAtIndex(self, index: int, val: int) -> None: def addAtIndex(self, index: int, val: int) -> None:
""" if index < 0 or index > self.size:
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.
"""
if index < 0:
index = 0
elif index > self._count:
return return
node = self._get_node(index)
self._update(node.prev, node, val) current = self.dummy_head
for i in range(index):
def _update(self, prev: Node, next: Node, val: int) -> None: current = current.next
""" current.next = ListNode(val, current.next)
更新节点 self.size += 1
:param prev: 相对于更新的前一个节点
:param next: 相对于更新的后一个节点
:param val: 要添加的节点值
"""
# 计数累加
self._count += 1
node = Node(val)
prev.next, next.prev = node, node
node.prev, node.next = prev, next
def deleteAtIndex(self, index: int) -> None: def deleteAtIndex(self, index: int) -> None:
""" if index < 0 or index >= self.size:
Delete the index-th node in the linked list, if the index is valid. return
"""
if 0 <= index < self._count: current = self.dummy_head
node = self._get_node(index) for i in range(index):
# 计数-1 current = current.next
self._count -= 1 current.next = current.next.next
node.prev.next, node.next.prev = node.next, node.prev self.size -= 1
# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)
```
```python
版本二双链表法
class ListNode:
def __init__(self, val=0, prev=None, next=None):
self.val = val
self.prev = prev
self.next = next
class MyLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def get(self, index: int) -> int:
if index < 0 or index >= self.size:
return -1
if index < self.size // 2:
current = self.head
for i in range(index):
current = current.next
else:
current = self.tail
for i in range(self.size - index - 1):
current = current.prev
return current.val
def addAtHead(self, val: int) -> None:
new_node = ListNode(val, None, self.head)
if self.head:
self.head.prev = new_node
else:
self.tail = new_node
self.head = new_node
self.size += 1
def addAtTail(self, val: int) -> None:
new_node = ListNode(val, self.tail, None)
if self.tail:
self.tail.next = new_node
else:
self.head = new_node
self.tail = new_node
self.size += 1
def addAtIndex(self, index: int, val: int) -> None:
if index < 0 or index > self.size:
return
if index == 0:
self.addAtHead(val)
elif index == self.size:
self.addAtTail(val)
else:
if index < self.size // 2:
current = self.head
for i in range(index - 1):
current = current.next
else:
current = self.tail
for i in range(self.size - index):
current = current.prev
new_node = ListNode(val, current, current.next)
current.next.prev = new_node
current.next = new_node
self.size += 1
def deleteAtIndex(self, index: int) -> None:
if index < 0 or index >= self.size:
return
if index == 0:
self.head = self.head.next
if self.head:
self.head.prev = None
else:
self.tail = None
elif index == self.size - 1:
self.tail = self.tail.prev
if self.tail:
self.tail.next = None
else:
self.head = None
else:
if index < self.size // 2:
current = self.head
for i in range(index):
current = current.next
else:
current = self.tail
for i in range(self.size - index - 1):
current = current.prev
current.prev.next = current.next
current.next.prev = current.prev
self.size -= 1
# Your MyLinkedList object will be instantiated and called as such:
# obj = MyLinkedList()
# param_1 = obj.get(index)
# obj.addAtHead(val)
# obj.addAtTail(val)
# obj.addAtIndex(index,val)
# obj.deleteAtIndex(index)
``` ```
Go Go

View File

@ -140,22 +140,37 @@ class Solution {
Python Python
```Python ```Python
版本一双指针法
class Solution: class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]: def sortedSquares(self, nums: List[int]) -> List[int]:
n = len(nums) l, r, i = 0, len(nums)-1, len(nums)-1
i,j,k = 0,n - 1,n - 1 res = [float('inf')] * len(nums) # 需要提前定义列表,存放结果
ans = [-1] * n while l <= r:
while i <= j: if nums[l] ** 2 < nums[r] ** 2: # 左右边界进行对比,找出最大值
lm = nums[i] ** 2 res[i] = nums[r] ** 2
rm = nums[j] ** 2 r -= 1 # 右指针往左移动
if lm > rm:
ans[k] = lm
i += 1
else: else:
ans[k] = rm res[i] = nums[l] ** 2
j -= 1 l += 1 # 左指针往右移动
k -= 1 i -= 1 # 存放结果的指针需要往前平移一位
return ans return res
```
```Python
版本二暴力排序法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
for i in range(len(nums)):
nums[i] *= nums[i]
nums.sort()
return nums
```
```Python
版本三暴力排序法+列表推导法
class Solution:
def sortedSquares(self, nums: List[int]) -> List[int]:
return sorted(x*x for x in nums)
``` ```
Go Go

View File

@ -258,7 +258,9 @@ class Solution:
if node.left: if node.left:
stack.append(node.left) stack.append(node.left)
return result return result
```
```python
# 中序遍历-迭代-LC94_二叉树的中序遍历 # 中序遍历-迭代-LC94_二叉树的中序遍历
class Solution: class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]: def inorderTraversal(self, root: TreeNode) -> List[int]:
@ -279,7 +281,9 @@ class Solution:
# 取栈顶元素右结点 # 取栈顶元素右结点
cur = cur.right cur = cur.right
return result return result
```
```python
# 后序遍历-迭代-LC145_二叉树的后序遍历 # 后序遍历-迭代-LC145_二叉树的后序遍历
class Solution: class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]: def postorderTraversal(self, root: TreeNode) -> List[int]:

View File

@ -174,50 +174,49 @@ class Solution {
Python Python
```python ```python
# 前序遍历-递归-LC144_二叉树的前序遍历 # 前序遍历-递归-LC144_二叉树的前序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution: class Solution:
def preorderTraversal(self, root: TreeNode) -> List[int]: def preorderTraversal(self, root: TreeNode) -> List[int]:
# 保存结果 if not root:
result = [] return []
def traversal(root: TreeNode):
if root == None:
return
result.append(root.val) # 前序
traversal(root.left) # 左
traversal(root.right) # 右
traversal(root) left = self.preorderTraversal(root.left)
return result right = self.preorderTraversal(root.right)
return [root.val] + left + right
```
```python
# 中序遍历-递归-LC94_二叉树的中序遍历 # 中序遍历-递归-LC94_二叉树的中序遍历
class Solution: class Solution:
def inorderTraversal(self, root: TreeNode) -> List[int]: def inorderTraversal(self, root: TreeNode) -> List[int]:
result = [] if root is None:
return []
def traversal(root: TreeNode): left = self.inorderTraversal(root.left)
if root == None: right = self.inorderTraversal(root.right)
return
traversal(root.left) # 左 return left + [root.val] + right
result.append(root.val) # 中序 ```
traversal(root.right) # 右 ```python
traversal(root)
return result
# 后序遍历-递归-LC145_二叉树的后序遍历 # 后序遍历-递归-LC145_二叉树的后序遍历
class Solution: class Solution:
def postorderTraversal(self, root: TreeNode) -> List[int]: def postorderTraversal(self, root: TreeNode) -> List[int]:
result = [] if not root:
return []
def traversal(root: TreeNode): left = self.postorderTraversal(root.left)
if root == None: right = self.postorderTraversal(root.right)
return
traversal(root.left) # 左
traversal(root.right) # 右
result.append(root.val) # 后序
traversal(root) return left + right + [root.val]
return result
``` ```
Go Go

View File

@ -24,5 +24,5 @@
例如for循环里套一个字符串的inserterase之类的操作你说时间复杂度是多少呢很明显是O(n^2)的时间复杂度了。 例如for循环里套一个字符串的inserterase之类的操作你说时间复杂度是多少呢很明显是O(n^2)的时间复杂度了。
在刷题的时候本着我说的标准来使用库函数,详细对大家有所帮助! 在刷题的时候本着我说的标准来使用库函数,相信对大家有所帮助!

View File

@ -266,6 +266,8 @@ func replaceSpace(s string) string {
python python
#### 因为字符串是不可变类型所以操作字符串需要将其转换为列表因此空间复杂度不可能为O(1)
(版本一)转换成列表,并且添加相匹配的空间,然后进行填充
```python ```python
class Solution: class Solution:
def replaceSpace(self, s: str) -> str: def replaceSpace(self, s: str) -> str:
@ -290,14 +292,22 @@ class Solution:
return ''.join(res) return ''.join(res)
``` ```
(版本二)添加空列表,添加匹配的结果
```python
class Solution:
def replaceSpace(self, s: str) -> str:
res = []
for i in range(len(s)):
if s[i] == ' ':
res.append('%20')
else:
res.append(s[i])
return ''.join(res)
```
(版本三)使用切片
```python ```python
class Solution: class Solution:
def replaceSpace(self, s: str) -> str: def replaceSpace(self, s: str) -> str:
# method 1 - Very rude
return "%20".join(s.split(" "))
# method 2 - Reverse the s when counting in for loop, then update from the end.
n = len(s) n = len(s)
for e, i in enumerate(s[::-1]): for e, i in enumerate(s[::-1]):
print(i, e) print(i, e)
@ -306,7 +316,18 @@ class Solution:
print("") print("")
return s return s
``` ```
版本四使用join + split
```python
class Solution:
def replaceSpace(self, s: str) -> str:
return "%20".join(s.split(" "))
```
版本五使用replace
```python
class Solution:
def replaceSpace(self, s: str) -> str:
return s.replace(' ', '%20')
```
javaScript: javaScript:
```js ```js

View File

@ -142,15 +142,16 @@ class Solution {
``` ```
python: python:
(版本一)使用切片
```python ```python
# 方法一:可以使用切片方法
class Solution: class Solution:
def reverseLeftWords(self, s: str, n: int) -> str: def reverseLeftWords(self, s: str, n: int) -> str:
return s[n:] + s[0:n] return s[n:] + s[:n]
``` ```
版本二使用reversed + join
```python ```python
# 方法二:也可以使用上文描述的方法,有些面试中不允许使用切片,那就使用上文作者提到的方法
class Solution: class Solution:
def reverseLeftWords(self, s: str, n: int) -> str: def reverseLeftWords(self, s: str, n: int) -> str:
s = list(s) s = list(s)
@ -161,32 +162,29 @@ class Solution:
return "".join(s) return "".join(s)
``` ```
版本三自定义reversed函数
```python ```python
# 方法三如果连reversed也不让使用那么自己手写一个
class Solution: class Solution:
def reverseLeftWords(self, s: str, n: int) -> str: def reverseLeftWords(self, s: str, n: int) -> str:
def reverse_sub(lst, left, right): s_list = list(s)
while left < right:
lst[left], lst[right] = lst[right], lst[left]
left += 1
right -= 1
res = list(s) self.reverse(s_list, 0, n - 1)
end = len(res) - 1 self.reverse(s_list, n, len(s_list) - 1)
reverse_sub(res, 0, n - 1) self.reverse(s_list, 0, len(s_list) - 1)
reverse_sub(res, n, end)
reverse_sub(res, 0, end)
return ''.join(res)
# 同方法二 return ''.join(s_list)
# 时间复杂度O(n)
# 空间复杂度O(n)python的string为不可变需要开辟同样大小的list空间来修改 def reverse(self, s, start, end):
while start < end:
s[start], s[end] = s[end], s[start]
start += 1
end -= 1
``` ```
(版本四)使用 模 +下标
```python 3 ```python 3
#方法四:考虑不能用切片的情况下,利用模+下标实现
class Solution: class Solution:
def reverseLeftWords(self, s: str, n: int) -> str: def reverseLeftWords(self, s: str, n: int) -> str:
new_s = '' new_s = ''
@ -196,17 +194,21 @@ class Solution:
return new_s return new_s
``` ```
(版本五)使用 模 + 切片
```python 3 ```python 3
# 方法五:另类的切片方法
class Solution: class Solution:
def reverseLeftWords(self, s: str, n: int) -> str: def reverseLeftWords(self, s: str, n: int) -> str:
n = len(s) l = len(s)
s = s + s # 复制输入字符串与它自己连接
return s[k : n+k] s = s + s
# 计算旋转字符串的起始索引
k = n % (l * 2)
# 从连接的字符串中提取旋转后的字符串并返回
return s[k : k + l]
# 时间复杂度O(n)
# 空间复杂度O(n)
``` ```
Go Go

View File

@ -150,9 +150,13 @@ public class Solution {
} }
``` ```
Python Python
```python ```python
版本一求长度同时出发
class Solution: class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
lenA, lenB = 0, 0 lenA, lenB = 0, 0
@ -178,8 +182,105 @@ class Solution:
curB = curB.next curB = curB.next
return None return None
``` ```
```python
版本二求长度同时出发 代码复用
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
lenA = self.getLength(headA)
lenB = self.getLength(headB)
# 通过移动较长的链表,使两链表长度相等
if lenA > lenB:
headA = self.moveForward(headA, lenA - lenB)
else:
headB = self.moveForward(headB, lenB - lenA)
# 将两个头向前移动,直到它们相交
while headA and headB:
if headA == headB:
return headA
headA = headA.next
headB = headB.next
return None
def getLength(self, head: ListNode) -> int:
length = 0
while head:
length += 1
head = head.next
return length
def moveForward(self, head: ListNode, steps: int) -> ListNode:
while steps > 0:
head = head.next
steps -= 1
return head
```
```python
版本三求长度同时出发 代码复用 + 精简
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
dis = self.getLength(headA) - self.getLength(headB)
# 通过移动较长的链表,使两链表长度相等
if dis > 0:
headA = self.moveForward(headA, dis)
else:
headB = self.moveForward(headB, abs(dis))
# 将两个头向前移动,直到它们相交
while headA and headB:
if headA == headB:
return headA
headA = headA.next
headB = headB.next
return None
def getLength(self, head: ListNode) -> int:
length = 0
while head:
length += 1
head = head.next
return length
def moveForward(self, head: ListNode, steps: int) -> ListNode:
while steps > 0:
head = head.next
steps -= 1
return head
```
```python
版本四等比例法
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
Go
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:
# 处理边缘情况
if not headA or not headB:
return None
# 在每个链表的头部初始化两个指针
pointerA = headA
pointerB = headB
# 遍历两个链表直到指针相交
while pointerA != pointerB:
# 将指针向前移动一个节点
pointerA = pointerA.next if pointerA else headB
pointerB = pointerB.next if pointerB else headA
# 如果相交指针将位于交点节点如果没有交点值为None
return pointerA
```
Go:
```go ```go
func getIntersectionNode(headA, headB *ListNode) *ListNode { func getIntersectionNode(headA, headB *ListNode) *ListNode {