diff --git a/problems/0015.三数之和.md b/problems/0015.三数之和.md
index dec8a7c6..1e675254 100644
--- a/problems/0015.三数之和.md
+++ b/problems/0015.三数之和.md
@@ -435,5 +435,79 @@ func threeSum(_ nums: [Int]) -> [[Int]] {
}
```
+C:
+```C
+//qsort辅助cmp函数
+int cmp(const void* ptr1, const void* ptr2) {
+ return *((int*)ptr1) > *((int*)ptr2);
+}
+
+int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes) {
+ //开辟ans数组空间
+ int **ans = (int**)malloc(sizeof(int*) * 18000);
+ int ansTop = 0;
+ //若传入nums数组大小小于3,则需要返回数组大小为0
+ if(numsSize < 3) {
+ *returnSize = 0;
+ return ans;
+ }
+ //对nums数组进行排序
+ qsort(nums, numsSize, sizeof(int), cmp);
+
+
+ int i;
+ //用for循环遍历数组,结束条件为i < numsSize - 2(因为要预留左右指针的位置)
+ for(i = 0; i < numsSize - 2; i++) {
+ //若当前i指向元素>0,则代表left和right以及i的和大于0。直接break
+ if(nums[i] > 0)
+ break;
+ //去重:i > 0 && nums[i] == nums[i-1]
+ if(i > 0 && nums[i] == nums[i-1])
+ continue;
+ //定义左指针和右指针
+ int left = i + 1;
+ int right = numsSize - 1;
+ //当右指针比左指针大时进行循环
+ while(right > left) {
+ //求出三数之和
+ int sum = nums[right] + nums[left] + nums[i];
+ //若和小于0,则左指针+1(因为左指针右边的数比当前所指元素大)
+ if(sum < 0)
+ left++;
+ //若和大于0,则将右指针-1
+ else if(sum > 0)
+ right--;
+ //若和等于0
+ else {
+ //开辟一个大小为3的数组空间,存入nums[i], nums[left]和nums[right]
+ int* arr = (int*)malloc(sizeof(int) * 3);
+ arr[0] = nums[i];
+ arr[1] = nums[left];
+ arr[2] = nums[right];
+ //将开辟数组存入ans中
+ ans[ansTop++] = arr;
+ //去重
+ while(right > left && nums[right] == nums[right - 1])
+ right--;
+ while(left < right && nums[left] == nums[left + 1])
+ left++;
+ //更新左右指针
+ left++;
+ right--;
+ }
+ }
+ }
+
+ //设定返回的数组大小
+ *returnSize = ansTop;
+ *returnColumnSizes = (int*)malloc(sizeof(int) * ansTop);
+ int z;
+ for(z = 0; z < ansTop; z++) {
+ (*returnColumnSizes)[z] = 3;
+ }
+ return ans;
+}
+```
+
-----------------------
diff --git a/problems/0019.删除链表的倒数第N个节点.md b/problems/0019.删除链表的倒数第N个节点.md
index e05b9d03..188c4c57 100644
--- a/problems/0019.删除链表的倒数第N个节点.md
+++ b/problems/0019.删除链表的倒数第N个节点.md
@@ -173,8 +173,7 @@ var removeNthFromEnd = function(head, n) {
let ret = new ListNode(0, head),
slow = fast = ret;
while(n--) fast = fast.next;
- if(!fast) return ret.next;
- while (fast.next) {
+ while (fast.next !== null) {
fast = fast.next;
slow = slow.next
};
diff --git a/problems/0040.组合总和II.md b/problems/0040.组合总和II.md
index bab4bd6a..b5e511e7 100644
--- a/problems/0040.组合总和II.md
+++ b/problems/0040.组合总和II.md
@@ -457,6 +457,37 @@ var combinationSum2 = function(candidates, target) {
}
};
```
+**使用used去重**
+```js
+var combinationSum2 = function(candidates, target) {
+ let res = [];
+ let path = [];
+ let total = 0;
+ const len = candidates.length;
+ candidates.sort((a, b) => a - b);
+ let used = new Array(len).fill(false);
+ const backtracking = (startIndex) => {
+ if (total === target) {
+ res.push([...path]);
+ return;
+ }
+ for(let i = startIndex; i < len && total < target; i++) {
+ const cur = candidates[i];
+ if (cur > target - total || (i > 0 && cur === candidates[i - 1] && !used[i - 1])) continue;
+ path.push(cur);
+ total += cur;
+ used[i] = true;
+ backtracking(i + 1);
+ path.pop();
+ total -= cur;
+ used[i] = false;
+ }
+ }
+ backtracking(0);
+ return res;
+};
+```
+
## C
```c
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index ec265615..82d1941e 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -414,19 +414,24 @@ class Solution:
import "math"
func isValidBST(root *TreeNode) bool {
- if root == nil {
- return true
- }
- return isBST(root, math.MinInt64, math.MaxFloat64)
+ // 二叉搜索树也可以是空树
+ if root == nil {
+ return true
+ }
+ // 由题目中的数据限制可以得出min和max
+ return check(root,math.MinInt64,math.MaxInt64)
}
-func isBST(root *TreeNode, min, max int) bool {
- if root == nil {
- return true
- }
- if min >= root.Val || max <= root.Val {
- return false
- }
- return isBST(root.Left, min, root.Val) && isBST(root.Right, root.Val, max)
+
+func check(node *TreeNode,min,max int64) bool {
+ if node == nil {
+ return true
+ }
+
+ if min >= int64(node.Val) || max <= int64(node.Val) {
+ return false
+ }
+ // 分别对左子树和右子树递归判断,如果左子树和右子树都符合则返回true
+ return check(node.Right,int64(node.Val),max) && check(node.Left,min,int64(node.Val))
}
```
```go
diff --git a/problems/0150.逆波兰表达式求值.md b/problems/0150.逆波兰表达式求值.md
index ef91330d..137aaf5d 100644
--- a/problems/0150.逆波兰表达式求值.md
+++ b/problems/0150.逆波兰表达式求值.md
@@ -241,6 +241,38 @@ class Solution:
```
+Swift:
+```Swift
+func evalRPN(_ tokens: [String]) -> Int {
+ var stack = [Int]()
+ for c in tokens {
+ let v = Int(c)
+ if let num = v {
+ // 遇到数字直接入栈
+ stack.append(num)
+ } else {
+ // 遇到运算符, 取出栈顶两元素计算, 结果压栈
+ var res: Int = 0
+ let num2 = stack.popLast()!
+ let num1 = stack.popLast()!
+ switch c {
+ case "+":
+ res = num1 + num2
+ case "-":
+ res = num1 - num2
+ case "*":
+ res = num1 * num2
+ case "/":
+ res = num1 / num2
+ default:
+ break
+ }
+ stack.append(res)
+ }
+ }
+ return stack.last!
+}
+```
-----------------------
diff --git a/problems/0205.同构字符串.md b/problems/0205.同构字符串.md
index a2963149..eeda7d2e 100644
--- a/problems/0205.同构字符串.md
+++ b/problems/0205.同构字符串.md
@@ -90,6 +90,24 @@ class Solution {
## Python
```python
+class Solution:
+ def isIsomorphic(self, s: str, t: str) -> bool:
+ default_dict1 = defaultdict(str)
+ default_dict2 = defaultdict(str)
+
+ if len(s) != len(t): return false
+
+ for i in range(len(s)):
+ if not default_dict1[s[i]]:
+ default_dict1[s[i]] = t[i]
+
+ if not default_dict2[t[i]]:
+ default_dict2[t[i]] = s[i]
+
+ if default_dict1[s[i]] != t[i] or default_dict2[t[i]] != s[i]:
+ return False
+
+ return True
```
## Go
diff --git a/problems/0236.二叉树的最近公共祖先.md b/problems/0236.二叉树的最近公共祖先.md
index 4182999f..6d26e376 100644
--- a/problems/0236.二叉树的最近公共祖先.md
+++ b/problems/0236.二叉树的最近公共祖先.md
@@ -221,42 +221,30 @@ public:
## Java
+
```Java
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
- return lowestCommonAncestor1(root, p, q);
- }
- public TreeNode lowestCommonAncestor1(TreeNode root, TreeNode p, TreeNode q) {
- if (root == null || root == p || root == q) {
+ if (root == null || root == p || root == q) { // 递归结束条件
return root;
}
- TreeNode left = lowestCommonAncestor1(root.left, p, q);
- TreeNode right = lowestCommonAncestor1(root.right, p, q);
- if (left != null && right != null) {// 左右子树分别找到了,说明此时的root就是要求的结果
- return root;
- }
- if (left == null) {
+
+ // 后序遍历
+ TreeNode left = lowestCommonAncestor(root.left, p, q);
+ TreeNode right = lowestCommonAncestor(root.right, p, q);
+
+ if(left == null && right == null) { // 若未找到节点 p 或 q
+ return null;
+ }else if(left == null && right != null) { // 若找到一个节点
return right;
+ }else if(left != null && right == null) { // 若找到一个节点
+ return left;
+ }else { // 若找到两个节点
+ return root;
}
- return left;
}
}
-```
-
-```java
-// 代码精简版
-class Solution {
- public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
- if (root == null || root.val == p.val ||root.val == q.val) return root;
- TreeNode left = lowestCommonAncestor(root.left,p,q);
- TreeNode right = lowestCommonAncestor(root.right,p,q);
- if (left != null && right != null) return root;
- else if (left == null && right != null) return right;
- else if (left != null && right == null) return left;
- else return null;
- }
-}
```
## Python
diff --git a/problems/0239.滑动窗口最大值.md b/problems/0239.滑动窗口最大值.md
index 8a8d3a52..1f245699 100644
--- a/problems/0239.滑动窗口最大值.md
+++ b/problems/0239.滑动窗口最大值.md
@@ -418,6 +418,112 @@ var maxSlidingWindow = function (nums, k) {
};
```
+Swift:
+```Swift
+/// 双向链表
+class DoublyListNode {
+ var head: DoublyListNode?
+ var tail: DoublyListNode?
+ var next: DoublyListNode?
+ var pre: DoublyListNode?
+ var value: Int = 0
+ init(_ value: Int = 0) {
+ self.value = value
+ }
+ func isEmpty() -> Bool {
+ return self.head == nil
+ }
+ func first() -> Int? {
+ return self.head?.value
+ }
+ func last() -> Int? {
+ return self.tail?.value
+ }
+ func removeFirst() {
+ if isEmpty() {
+ return
+ }
+ let next = self.head!.next
+ self.head?.next = nil// 移除首节点
+ next?.pre = nil
+ self.head = next
+ }
+ func removeLast() {
+ if let tail = self.tail {
+ if let pre = tail.pre {
+ self.tail?.pre = nil
+ pre.next = nil
+ self.tail = pre
+ } else {
+ self.head = nil
+ self.tail = nil
+ }
+ }
+ }
+ func append(_ value: Int) {
+ let node = DoublyListNode(value)
+ if self.head != nil {
+ node.pre = self.tail
+ self.tail?.next = node
+ self.tail = node
+ } else {
+ self.head = node
+ self.tail = node
+ self.pre = nil
+ self.next = nil
+ }
+ }
+}
+// 单调队列, 从大到小
+class MyQueue {
+// var queue: [Int]!// 用数组会超时
+ var queue: DoublyListNode!
+ init() {
+// queue = [Int]()
+ queue = DoublyListNode()
+ }
+ // 滑动窗口时弹出第一个元素, 如果相等再弹出
+ func pop(x: Int) {
+ if !queue.isEmpty() && front() == x {
+ queue.removeFirst()
+ }
+ }
+ // 滑动窗口时添加下一个元素, 移除队尾比 x 小的元素 始终保证队头 > 队尾
+ func push(x: Int) {
+ while !queue.isEmpty() && queue.last()! < x {
+ queue.removeLast()
+ }
+ queue.append(x)
+ }
+ // 此时队头就是滑动窗口最大值
+ func front() -> Int {
+ return queue.first() ?? -1
+ }
+}
+
+class Solution {
+ func maxSlidingWindow(_ nums: [Int], _ k: Int) -> [Int] {
+ // 存放结果
+ var res = [Int]()
+ let queue = MyQueue()
+ // 先将前K个元素放入队列
+ for i in 0 ..< k {
+ queue.push(x: nums[i])
+ }
+ // 添加当前队列最大值到结果数组
+ res.append(queue.front())
+ for i in k ..< nums.count {
+ // 滑动窗口移除最前面元素
+ queue.pop(x: nums[i - k])
+ // 滑动窗口添加下一个元素
+ queue.push(x: nums[i])
+ // 保存当前队列最大值
+ res.append(queue.front())
+ }
+ return res
+ }
+}
+```
-----------------------
diff --git a/problems/0416.分割等和子集.md b/problems/0416.分割等和子集.md
index b661a766..393baf7d 100644
--- a/problems/0416.分割等和子集.md
+++ b/problems/0416.分割等和子集.md
@@ -68,7 +68,7 @@
* 背包的体积为sum / 2
* 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
-* 背包如何正好装满,说明找到了总和为 sum / 2 的子集。
+* 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
* 背包中每一个元素是不可重复放入。
以上分析完,我们就可以套用01背包,来解决这个问题了。
diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md
index 5d63ce58..1e6ab47e 100644
--- a/problems/0701.二叉搜索树中的插入操作.md
+++ b/problems/0701.二叉搜索树中的插入操作.md
@@ -236,16 +236,13 @@ class Solution {
```java
class Solution {
public TreeNode insertIntoBST(TreeNode root, int val) {
- return buildTree(root, val);
- }
-
- public TreeNode buildTree(TreeNode root, int val){
if (root == null) // 如果当前节点为空,也就意味着val找到了合适的位置,此时创建节点直接返回。
return new TreeNode(val);
+
if (root.val < val){
- root.right = buildTree(root.right, val); // 递归创建右子树
+ root.right = insertIntoBST(root.right, val); // 递归创建右子树
}else if (root.val > val){
- root.left = buildTree(root.left, val); // 递归创建左子树
+ root.left = insertIntoBST(root.left, val); // 递归创建左子树
}
return root;
}
diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md
index bb10143f..44a0c1d8 100644
--- a/problems/0704.二分查找.md
+++ b/problems/0704.二分查找.md
@@ -276,11 +276,9 @@ func search(nums []int, target int) int {
```
**JavaScript:**
+(版本一)左闭右闭区间
```js
-
-// (版本一)左闭右闭区间
-
/**
* @param {number[]} nums
* @param {number} target
@@ -302,9 +300,10 @@ var search = function(nums, target) {
}
return -1;
};
+```
+(版本二)左闭右开区间
-// (版本二)左闭右开区间
-
+```js
/**
* @param {number[]} nums
* @param {number} target
@@ -325,7 +324,6 @@ var search = function(nums, target) {
}
return -1;
};
-
```
**Ruby:**
diff --git a/problems/0977.有序数组的平方.md b/problems/0977.有序数组的平方.md
index b1e04c4e..6616ba8c 100644
--- a/problems/0977.有序数组的平方.md
+++ b/problems/0977.有序数组的平方.md
@@ -199,27 +199,26 @@ impl Solution {
Javascript:
```Javascript
/**
- * @desc two pointers solution
- * @link https://leetcode-cn.com/problems/squares-of-a-sorted-array/
- * @param nums Array e.g. [-4,-1,0,3,10]
- * @return {array} e.g. [0,1,9,16,100]
+ * @param {number[]} nums
+ * @return {number[]}
*/
-const sortedSquares = function (nums) {
- let res = []
- for (let i = 0, j = nums.length - 1; i <= j;) {
- const left = Math.abs(nums[i])
- const right = Math.abs(nums[j])
- if (right > left) {
- // push element to the front of the array
- res.unshift(right * right)
- j--
- } else {
- res.unshift(left * left)
- i++
- }
+var sortedSquares = function(nums) {
+ let n = nums.length;
+ let res = new Array(n).fill(0);
+ let i = 0, j = n - 1, k = n - 1;
+ while (i <= j) {
+ let left = nums[i] * nums[i],
+ right = nums[j] * nums[j];
+ if (left < right) {
+ res[k--] = right;
+ j--;
+ } else {
+ res[k--] = left;
+ i++;
+ }
}
- return res
- }
+ return res;
+};
```
Swift:
diff --git a/problems/算法模板.md b/problems/算法模板.md
index 853816d2..69ebb361 100644
--- a/problems/算法模板.md
+++ b/problems/算法模板.md
@@ -460,7 +460,7 @@ var levelOrder = function (root) {
for (let i = 0; i < n; i++) {
let node = queue.shift();
temp.push(node.val);
- node.left &&queue.push(node.left);
+ node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
res.push(temp);