diff --git a/problems/0101.对称二叉树.md b/problems/0101.对称二叉树.md index d8797d30..b58cef2e 100644 --- a/problems/0101.对称二叉树.md +++ b/problems/0101.对称二叉树.md @@ -363,6 +363,54 @@ Python: Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +// 递归 +func defs(left *TreeNode, right *TreeNode) bool { + if left == nil && right == nil { + return true; + }; + if left == nil || right == nil { + return false; + }; + if left.Val != right.Val { + return false; + } + return defs(left.Left, right.Right) && defs(right.Left, left.Right); +} +func isSymmetric(root *TreeNode) bool { + return defs(root.Left, root.Right); +} + +// 迭代 +func isSymmetric(root *TreeNode) bool { + var queue []*TreeNode; + if root != nil { + queue = append(queue, root.Left, root.Right); + } + for len(queue) > 0 { + left := queue[0]; + right := queue[1]; + queue = queue[2:]; + if left == nil && right == nil { + continue; + } + if left == nil || right == nil || left.Val != right.Val { + return false; + }; + queue = append(queue, left.Left, right.Right, right.Left, left.Right); + } + return true; +} +``` + JavaScript ```javascript diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md index 756afb68..5f0fe411 100644 --- a/problems/0104.二叉树的最大深度.md +++ b/problems/0104.二叉树的最大深度.md @@ -284,6 +284,55 @@ Python: Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func max (a, b int) int { + if a > b { + return a; + } + return b; +} +// 递归 +func maxDepth(root *TreeNode) int { + if root == nil { + return 0; + } + return max(maxDepth(root.Left), maxDepth(root.Right)) + 1; +} + +// 遍历 +func maxDepth(root *TreeNode) int { + levl := 0; + queue := make([]*TreeNode, 0); + if root != nil { + queue = append(queue, root); + } + for l := len(queue); l > 0; { + for ;l > 0;l-- { + node := queue[0]; + if node.Left != nil { + queue = append(queue, node.Left); + } + if node.Right != nil { + queue = append(queue, node.Right); + } + queue = queue[1:]; + } + levl++; + l = len(queue); + } + return levl; +} + +``` + JavaScript ```javascript diff --git a/problems/0111.二叉树的最小深度.md b/problems/0111.二叉树的最小深度.md index 8ee15eac..48795722 100644 --- a/problems/0111.二叉树的最小深度.md +++ b/problems/0111.二叉树的最小深度.md @@ -301,6 +301,64 @@ class Solution: Go: +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func min(a, b int) int { + if a < b { + return a; + } + return b; +} +// 递归 +func minDepth(root *TreeNode) int { + if root == nil { + return 0; + } + if root.Left == nil && root.Right != nil { + return 1 + minDepth(root.Right); + } + if root.Right == nil && root.Left != nil { + return 1 + minDepth(root.Left); + } + return min(minDepth(root.Left), minDepth(root.Right)) + 1; +} + +// 迭代 + +func minDepth(root *TreeNode) int { + dep := 0; + queue := make([]*TreeNode, 0); + if root != nil { + queue = append(queue, root); + } + for l := len(queue); l > 0; { + dep++; + for ; l > 0; l-- { + node := queue[0]; + if node.Left == nil && node.Right == nil { + return dep; + } + if node.Left != nil { + queue = append(queue, node.Left); + } + if node.Right != nil { + queue = append(queue, node.Right); + } + queue = queue[1:]; + } + l = len(queue); + } + return dep; +} +``` + JavaScript: diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index ed17157a..47383a47 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -263,6 +263,41 @@ class Solution { ``` Python: +```python +class MyQueue: #单调队列(从大到小 + def __init__(self): + self.queue = [] #使用list来实现单调队列 + + #每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。 + #同时pop之前判断队列当前是否为空。 + def pop(self, value): + if self.queue and value == self.queue[0]: + self.queue.pop(0)#list.pop()时间复杂度为O(n),这里可以使用collections.deque() + + #如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。 + #这样就保持了队列里的数值是单调从大到小的了。 + def push(self, value): + while self.queue and value > self.queue[-1]: + self.queue.pop() + self.queue.append(value) + + #查询当前队列里的最大值 直接返回队列前端也就是front就可以了。 + def front(self): + return self.queue[0] + +class Solution: + def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]: + que = MyQueue() + result = [] + for i in range(k): #先将前k的元素放进队列 + que.push(nums[i]) + result.append(que.front()) #result 记录前k的元素的最大值 + for i in range(k, len(nums)): + que.pop(nums[i - k]) #滑动窗口移除最前面元素 + que.push(nums[i]) #滑动窗口前加入最后面的元素 + result.append(que.front()) #记录对应的最大值 + return result +``` Go: diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md index 29963b48..71af618e 100644 --- a/problems/0347.前K个高频元素.md +++ b/problems/0347.前K个高频元素.md @@ -163,64 +163,33 @@ class Solution { Python: ```python +#时间复杂度:O(nlogk) +#空间复杂度:O(n) +import heapq class Solution: - def sift(self, alist, low, high): - '''小根堆构建''' - i = low - j = 2 * i + 1 - tmp = alist[low] - while j <= high: - if j + 1 <= high and alist[j+1] <= alist[j]: - j += 1 - if alist[j] < tmp: - alist[i] = alist[j] - i = j - j = 2 * i + 1 - else: - alist[i] = tmp - break - else: - alist[i] = tmp - - - def topK(self, nums, k): - # 建立小根堆 - heap = nums[:k] - for i in range((k-2)//2, -1, -1): - self.sift(heap, i, k-1) - - # 把后续的k到len(nums)填充到小根堆里 - for i in range(k, len(nums)): - if nums[i] >= heap[0]: - heap[0] = nums[i] - self.sift(heap, 0, k-1) - - # 排序 - for i in range(k-1, -1, -1): - heap[0], heap[i]= heap[i], heap[0] - self.sift(heap, 0, i-1) - return heap - def topKFrequent(self, nums: List[int], k: int) -> List[int]: - dict1 = dict() - for val in nums: - if val not in dict1: - dict1[val] = 1 - else: - dict1[val] += 1 - res = list() - ind = list() - for item in dict1: - res.append([dict1[item], item]) - result = list() - heap = self.topK(res, k) - print(heap) - for val in heap: - result.append(val[1]) + #要统计元素出现频率 + map_ = {} #nums[i]:对应出现的次数 + for i in range(len(nums)): + map_[nums[i]] = map_.get(nums[i], 0) + 1 + + #对频率排序 + #定义一个小顶堆,大小为k + pri_que = [] #小顶堆 + + #用固定大小为k的小顶堆,扫面所有频率的数值 + for key, freq in map_.items(): + heapq.heappush(pri_que, (freq, key)) + if len(pri_que) > k: #如果堆的大小大于了K,则队列弹出,保证堆的大小一直为k + heapq.heappop(pri_que) + + #找出前K个高频元素,因为小顶堆先弹出的是最小的,所以倒叙来输出到数组 + result = [0] * k + for i in range(k-1, -1, -1): + result[i] = heapq.heappop(pri_que)[1] return result ``` - Go: diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md index d9dfc62c..51a903ef 100644 --- a/problems/0459.重复的子字符串.md +++ b/problems/0459.重复的子字符串.md @@ -184,6 +184,55 @@ class Solution { Python: +这里使用了前缀表统一减一的实现方式 + +```python +class Solution: + def repeatedSubstringPattern(self, s: str) -> bool: + if len(s) == 0: + return False + nxt = [0] * len(s) + self.getNext(nxt, s) + if nxt[-1] != -1 and len(s) % (len(s) - (nxt[-1] + 1)) == 0: + return True + return False + + def getNext(self, nxt, s): + nxt[0] = -1 + j = -1 + for i in range(1, len(s)): + while j >= 0 and s[i] != s[j+1]: + j = nxt[j] + if s[i] == s[j+1]: + j += 1 + nxt[i] = j + return nxt +``` + +前缀表(不减一)的代码实现 + +```python +class Solution: + def repeatedSubstringPattern(self, s: str) -> bool: + if len(s) == 0: + return False + nxt = [0] * len(s) + self.getNext(nxt, s) + if nxt[-1] != 0 and len(s) % (len(s) - nxt[-1]) == 0: + return True + return False + + def getNext(self, nxt, s): + nxt[0] = 0 + j = 0 + for i in range(1, len(s)): + while j > 0 and s[i] != s[j]: + j = nxt[j - 1] + if s[i] == s[j]: + j += 1 + nxt[i] = j + return nxt +``` Go: diff --git a/problems/二叉树的统一迭代法.md b/problems/二叉树的统一迭代法.md index f4091ad5..533bdfe7 100644 --- a/problems/二叉树的统一迭代法.md +++ b/problems/二叉树的统一迭代法.md @@ -239,7 +239,78 @@ Java: ``` Python: +> 迭代法前序遍历 +```python +class Solution: + def preorderTraversal(self, root: TreeNode) -> List[int]: + result = [] + st= [] + if root: + st.append(root) + while st: + node = st.pop() + if node != None: + if node.right: #右 + st.append(node.right) + if node.left: #左 + st.append(node.left) + st.append(node) #中 + st.append(None) + else: + node = st.pop() + result.append(node.val) + return result +``` + +> 迭代法中序遍历 +```python +class Solution: + def inorderTraversal(self, root: TreeNode) -> List[int]: + result = [] + st = [] + if root: + st.append(root) + while st: + node = st.pop() + if node != None: + if node.right: #添加右节点(空节点不入栈) + st.append(node.right) + + st.append(node) #添加中节点 + st.append(None) #中节点访问过,但是还没有处理,加入空节点做为标记。 + + if node.left: #添加左节点(空节点不入栈) + st.append(node.left) + else: #只有遇到空节点的时候,才将下一个节点放进结果集 + node = st.pop() #重新取出栈中元素 + result.append(node.val) #加入到结果集 + return result +``` + +> 迭代法后序遍历 +```python +class Solution: + def postorderTraversal(self, root: TreeNode) -> List[int]: + result = [] + st = [] + if root: + st.append(root) + while st: + node = st.pop() + if node != None: + st.append(node) #中 + st.append(None) + + if node.right: #右 + st.append(node.right) + if node.left: #左 + st.append(node.left) + else: + node = st.pop() + result.append(node.val) + return result +``` Go: > 前序遍历统一迭代法