diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md index d108335b..ad54a940 100644 --- a/problems/0239.滑动窗口最大值.md +++ b/problems/0239.滑动窗口最大值.md @@ -208,6 +208,7 @@ public: Java: ```Java +//解法一 //自定义数组 class MyQueue { Deque deque = new LinkedList<>(); @@ -260,6 +261,40 @@ class Solution { return res; } } + +//解法二 +//利用双端队列手动实现单调队列 +/** + * 用一个单调队列来存储对应的下标,每当窗口滑动的时候,直接取队列的头部指针对应的值放入结果集即可 + * 单调队列类似 (tail -->) 3 --> 2 --> 1 --> 0 (--> head) (右边为头结点,元素存的是下标) + */ +class Solution { + public int[] maxSlidingWindow(int[] nums, int k) { + ArrayDeque deque = new ArrayDeque<>(); + int n = nums.length; + int[] res = new int[n - k + 1]; + int idx = 0; + for(int i = 0; i < n; i++) { + // 根据题意,i为nums下标,是要在[i - k + 1, k] 中选到最大值,只需要保证两点 + // 1.队列头结点需要在[i - k + 1, k]范围内,不符合则要弹出 + while(!deque.isEmpty() && deque.peek() < i - k + 1){ + deque.poll(); + } + // 2.既然是单调,就要保证每次放进去的数字要比末尾的都大,否则也弹出 + while(!deque.isEmpty() && nums[deque.peekLast()] < nums[i]) { + deque.pollLast(); + } + + deque.offer(i); + + // 因为单调,当i增长到符合第一个k范围的时候,每滑动一步都将队列头节点放入结果就行了 + if(i >= k - 1){ + res[idx++] = nums[deque.peek()]; + } + } + return res; + } +} ``` Python: diff --git a/problems/0344.反转字符串.md b/problems/0344.反转字符串.md index fd395ce6..aeb13a30 100644 --- a/problems/0344.反转字符串.md +++ b/problems/0344.反转字符串.md @@ -155,7 +155,7 @@ class Solution { ``` Python: -```python3 +```python class Solution: def reverseString(self, s: List[str]) -> None: """ @@ -166,6 +166,17 @@ class Solution: s[left], s[right] = s[right], s[left] left += 1 right -= 1 + +# 下面的写法更加简洁,但是都是同样的算法 +# class Solution: +# def reverseString(self, s: List[str]) -> None: +# """ +# Do not return anything, modify s in-place instead. +# """ + # 不需要判别是偶数个还是奇数个序列,因为奇数个的时候,中间那个不需要交换就可 +# for i in range(len(s)//2): +# s[i], s[len(s)-1-i] = s[len(s)-1-i], s[i] +# return s ``` Go: diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md index 9aca5b94..946c41ce 100644 --- a/problems/0406.根据身高重建队列.md +++ b/problems/0406.根据身高重建队列.md @@ -214,13 +214,10 @@ Python: ```python class Solution: def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: - people.sort(key=lambda x: (x[0], -x[1]), reverse=True) + people.sort(key=lambda x: (-x[0], x[1])) que = [] for p in people: - if p[1] > len(que): - que.append(p) - else: - que.insert(p[1], p) + que.insert(p[1], p) return que ``` diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md index 2ff093a3..f325df64 100644 --- a/problems/0617.合并二叉树.md +++ b/problems/0617.合并二叉树.md @@ -368,6 +368,20 @@ func mergeTrees(t1 *TreeNode, t2 *TreeNode) *TreeNode { Right: mergeTrees(t1.Right,t2.Right)} return root } + +// 前序遍历简洁版 +func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode { + if root1 == nil { + return root2 + } + if root2 == nil { + return root1 + } + root1.Val += root2.Val + root1.Left = mergeTrees(root1.Left, root2.Left) + root1.Right = mergeTrees(root1.Right, root2.Right) + return root1 +} ``` JavaScript: diff --git a/problems/1047.删除字符串中的所有相邻重复项.md b/problems/1047.删除字符串中的所有相邻重复项.md index 305a287d..760a0946 100644 --- a/problems/1047.删除字符串中的所有相邻重复项.md +++ b/problems/1047.删除字符串中的所有相邻重复项.md @@ -127,7 +127,9 @@ Java: ```Java class Solution { public String removeDuplicates(String S) { - Deque deque = new LinkedList<>(); + //ArrayDeque会比LinkedList在除了删除元素这一点外会快一点 + //参考:https://stackoverflow.com/questions/6163166/why-is-arraydeque-better-than-linkedlist + ArrayDeque deque = new ArrayDeque<>(); char ch; for (int i = 0; i < S.length(); i++) { ch = S.charAt(i); @@ -171,6 +173,29 @@ class Solution { } ``` +拓展:双指针 +```java +class Solution { + public String removeDuplicates(String s) { + char[] ch = s.toCharArray(); + int fast = 0; + int slow = 0; + while(fast < s.length()){ + // 直接用fast指针覆盖slow指针的值 + ch[slow] = ch[fast]; + // 遇到前后相同值的,就跳过,即slow指针后退一步,下次循环就可以直接被覆盖掉了 + if(slow > 0 && ch[slow] == ch[slow - 1]){ + slow--; + }else{ + slow++; + } + fast++; + } + return new String(ch,0,slow); + } +} +``` + Python: ```python3 class Solution: diff --git a/problems/二叉树的迭代遍历.md b/problems/二叉树的迭代遍历.md index 8706dc47..30b921ff 100644 --- a/problems/二叉树的迭代遍历.md +++ b/problems/二叉树的迭代遍历.md @@ -155,9 +155,82 @@ public: ## 其他语言版本 - Java: +```java +// 前序遍历顺序:中-左-右,入栈顺序:中-右-左 +class Solution { + public List preorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null){ + return result; + } + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()){ + TreeNode node = stack.pop(); + result.add(node.val); + if (node.right != null){ + stack.push(node.right); + } + if (node.left != null){ + stack.push(node.left); + } + } + return result; + } +} + +// 中序遍历顺序: 左-中-右 入栈顺序: 左-右 +class Solution { + public List inorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null){ + return result; + } + Stack stack = new Stack<>(); + TreeNode cur = root; + while (cur != null || !stack.isEmpty()){ + if (cur != null){ + stack.push(cur); + cur = cur.left; + }else{ + cur = stack.pop(); + result.add(cur.val); + cur = cur.right; + } + } + return result; + } +} + +// 后序遍历顺序 左-右-中 入栈顺序:中-左-右 出栈顺序:中-右-左, 最后翻转结果 +class Solution { + public List postorderTraversal(TreeNode root) { + List result = new ArrayList<>(); + if (root == null){ + return result; + } + Stack stack = new Stack<>(); + stack.push(root); + while (!stack.isEmpty()){ + TreeNode node = stack.pop(); + result.add(node.val); + if (node.left != null){ + stack.push(node.left); + } + if (node.right != null){ + stack.push(node.right); + } + } + Collections.reverse(result); + return result; + } +} +``` + + + Python: ```python3