From 60f61199853b5de43994ecf482643a855cafb0ee Mon Sep 17 00:00:00 2001
From: kok-s0s <2694308562@qq.com>
Date: Fri, 23 Jul 2021 19:14:29 +0800
Subject: [PATCH 001/138] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E5=B7=A6=E6=97=8B=E8=BD=AC=E5=AD=97?=
=?UTF-8?q?=E7=AC=A6=E4=B8=B2=E3=80=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/剑指Offer58-II.左旋转字符串.md | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md
index 1701086e..1f57b4af 100644
--- a/problems/剑指Offer58-II.左旋转字符串.md
+++ b/problems/剑指Offer58-II.左旋转字符串.md
@@ -162,7 +162,27 @@ func reverse(b []byte, left, right int){
}
```
+JavaScript版本
+```javascript
+/**
+ * @param {string} s
+ * @param {number} n
+ * @return {string}
+ */
+var reverseLeftWords = function (s, n) {
+ const reverse = (str, left, right) => {
+ let strArr = str.split("");
+ for (; left < right; left++, right--) {
+ [strArr[left], strArr[right]] = [strArr[right], strArr[left]];
+ }
+ return strArr.join("");
+ }
+ s = reverse(s, 0, n - 1);
+ s = reverse(s, n, s.length - 1);
+ return reverse(s, 0, s.length - 1);
+};
+```
From 45e996805b4ce94676abb1d5a2e43098403a6a6c Mon Sep 17 00:00:00 2001
From: SwordsmanYao
Date: Tue, 27 Jul 2021 16:44:04 +0800
Subject: [PATCH 002/138] =?UTF-8?q?[=E5=89=91=E6=8C=87Offer58-II.=E5=B7=A6?=
=?UTF-8?q?=E6=97=8B=E8=BD=AC=E5=AD=97=E7=AC=A6=E4=B8=B2]=20=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0js=E7=89=88=E6=9C=AC=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/剑指Offer58-II.左旋转字符串.md | 31 +++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/problems/剑指Offer58-II.左旋转字符串.md b/problems/剑指Offer58-II.左旋转字符串.md
index 3c3eaef0..8a60252c 100644
--- a/problems/剑指Offer58-II.左旋转字符串.md
+++ b/problems/剑指Offer58-II.左旋转字符串.md
@@ -165,6 +165,37 @@ func reverse(b []byte, left, right int){
```
+javaScript:
+
+```js
+/**
+ * @param {string} s
+ * @param {number} n
+ * @return {string}
+ */
+ var reverseLeftWords = function(s, n) {
+ const strArr = Array.from(s);
+ reverse(strArr, 0, n - 1);
+ reverse(strArr, n, strArr.length - 1);
+ reverse(strArr, 0, strArr.length - 1);
+ return strArr.join('');
+};
+
+// 翻转从 start 到 end 的字符
+function reverse(strArr, start, end) {
+ let left = start;
+ let right = end;
+
+ while(left < right) {
+ // 交换
+ [strArr[left], strArr[right]] = [strArr[right], strArr[left]];
+ left++;
+ right--;
+ }
+}
+```
+
+
From 877c8ca4188c59e792e78ee8619f7dc1657b0666 Mon Sep 17 00:00:00 2001
From: ylzou
Date: Tue, 27 Jul 2021 16:37:17 +0100
Subject: [PATCH 003/138] =?UTF-8?q?Update=200435.=E6=97=A0=E9=87=8D?=
=?UTF-8?q?=E5=8F=A0=E5=8C=BA=E9=97=B4.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Java,按左边排序,不管右边顺序。相交的时候取最小的右边。
---
problems/0435.无重叠区间.md | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/problems/0435.无重叠区间.md b/problems/0435.无重叠区间.md
index 37bb0b5d..d32c2ebb 100644
--- a/problems/0435.无重叠区间.md
+++ b/problems/0435.无重叠区间.md
@@ -211,6 +211,29 @@ class Solution {
}
```
+Java:
+按左边排序,不管右边顺序。相交的时候取最小的右边。
+```java
+class Solution {
+ public int eraseOverlapIntervals(int[][] intervals) {
+
+ Arrays.sort(intervals,(a,b)->{
+ return Integer.compare(a[0],b[0]);
+ });
+ int remove = 0;
+ int pre = intervals[0][1];
+ for(int i=1;iintervals[i][0]) {
+ remove++;
+ pre = Math.min(pre,intervals[i][1]);
+ }
+ else pre = intervals[i][1];
+ }
+ return remove;
+ }
+}
+```
+
Python:
```python
class Solution:
From 79fd10a6c498b5a3313738da41e653ccb1ab4580 Mon Sep 17 00:00:00 2001
From: posper
Date: Wed, 28 Jul 2021 14:13:51 +0800
Subject: [PATCH 004/138] =?UTF-8?q?283.=20=E7=A7=BB=E5=8A=A8=E9=9B=B6=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0283.移动零.md | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/problems/0283.移动零.md b/problems/0283.移动零.md
index 56f96b2f..8db42a0a 100644
--- a/problems/0283.移动零.md
+++ b/problems/0283.移动零.md
@@ -64,6 +64,21 @@ public:
Java:
+```java
+public void moveZeroes(int[] nums) {
+ int slow = 0;
+ for (int fast = 0; fast < nums.length; fast++) {
+ if (nums[fast] != 0) {
+ nums[slow++] = nums[fast];
+ }
+ }
+ // 后面的元素全变成 0
+ for (int j = slow; j < nums.length; j++) {
+ nums[j] = 0;
+ }
+ }
+```
+
Python:
```python
From 8b15ec147c2027f48f4d211d0f7e1c8c1d26d7c6 Mon Sep 17 00:00:00 2001
From: posper
Date: Wed, 28 Jul 2021 14:21:34 +0800
Subject: [PATCH 005/138] =?UTF-8?q?141.=20=E7=8E=AF=E5=BD=A2=E9=93=BE?=
=?UTF-8?q?=E8=A1=A8=20=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0141.环形链表.md | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/problems/0141.环形链表.md b/problems/0141.环形链表.md
index 4a40f953..0871202d 100644
--- a/problems/0141.环形链表.md
+++ b/problems/0141.环形链表.md
@@ -14,7 +14,7 @@
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
如果链表中存在环,则返回 true 。 否则,返回 false 。
-
+

# 思路
@@ -74,6 +74,21 @@ public:
## Java
```java
+public class Solution {
+ public boolean hasCycle(ListNode head) {
+ ListNode fast = head;
+ ListNode slow = head;
+ // 空链表、单节点链表一定不会有环
+ while (fast != null && fast.next != null) {
+ fast = fast.next.next; // 快指针,一次移动两步
+ slow = slow.next; // 慢指针,一次移动一步
+ if (fast == slow) { // 快慢指针相遇,表明有环
+ return true;
+ }
+ }
+ return false; // 正常走到链表末尾,表明没有环
+ }
+}
```
## Python
From 3be442c833eb21e1d7084cc44a898bf4ef951627 Mon Sep 17 00:00:00 2001
From: posper
Date: Wed, 28 Jul 2021 14:47:26 +0800
Subject: [PATCH 006/138] =?UTF-8?q?0941.=E6=9C=89=E6=95=88=E7=9A=84?=
=?UTF-8?q?=E5=B1=B1=E8=84=89=E6=95=B0=E7=BB=84=20=E6=B7=BB=E5=8A=A0Java?=
=?UTF-8?q?=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0941.有效的山脉数组.md | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/problems/0941.有效的山脉数组.md b/problems/0941.有效的山脉数组.md
index 6dbc3da2..167cfb1a 100644
--- a/problems/0941.有效的山脉数组.md
+++ b/problems/0941.有效的山脉数组.md
@@ -18,7 +18,7 @@ https://leetcode-cn.com/problems/valid-mountain-array/
C++代码如下:
-```
+```c++
class Solution {
public:
bool validMountainArray(vector& A) {
@@ -38,6 +38,33 @@ public:
}
};
```
+Java 版本如下:
+
+```java
+class Solution {
+ public boolean validMountainArray(int[] arr) {
+ if (arr.length < 3) { // 此时,一定不是有效的山脉数组
+ return false;
+ }
+ // 双指针
+ int left = 0;
+ int right = arr.length - 1;
+ // 注意防止指针越界
+ while (left + 1 < arr.length && arr[left] < arr[left + 1]) {
+ left++;
+ }
+ // 注意防止指针越界
+ while (right > 0 && arr[right] < arr[right - 1]) {
+ right--;
+ }
+ // 如果left或者right都在起始位置,说明不是山峰
+ if (left == right && left != 0 && right != arr.length - 1) {
+ return true;
+ }
+ return false;
+ }
+}
+```
+
如果想系统学一学双指针的话, 可以看一下这篇[双指针法:总结篇!](https://mp.weixin.qq.com/s/_p7grwjISfMh0U65uOyCjA)
-
From 32ffbe028816905ea510472d72d40aae7bd4fb4f Mon Sep 17 00:00:00 2001
From: posper
Date: Wed, 28 Jul 2021 15:08:14 +0800
Subject: [PATCH 007/138] =?UTF-8?q?34.=20=E5=9C=A8=E6=8E=92=E5=BA=8F?=
=?UTF-8?q?=E6=95=B0=E7=BB=84=E4=B8=AD=E6=9F=A5=E6=89=BE=E5=85=83=E7=B4=A0?=
=?UTF-8?q?=E7=9A=84=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=92=8C=E6=9C=80=E5=90=8E?=
=?UTF-8?q?=E4=B8=80=E4=B8=AA=E4=BD=8D=E7=BD=AE=EF=BC=8C=E6=B7=BB=E5=8A=A0?=
=?UTF-8?q?Java=E7=89=88=E6=9C=AC&=E8=A7=A3=E6=B3=952?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...排序数组中查找元素的第一个和最后一个位置.md | 100 +++++++++++++++++-
1 file changed, 98 insertions(+), 2 deletions(-)
diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
index 04f5eaf7..97b9a9b6 100644
--- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
+++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
@@ -14,7 +14,7 @@
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
-
+
示例 1:
* 输入:nums = [5,7,7,8,8,10], target = 8
@@ -173,8 +173,105 @@ private:
## Java
```java
+class Solution {
+ int[] searchRange(int[] nums, int target) {
+ int leftBorder = getLeftBorder(nums, target);
+ int rightBorder = getRightBorder(nums, target);
+ // 情况一
+ if (leftBorder == -2 || rightBorder == -2) return new int[]{-1, -1};
+ // 情况三
+ if (rightBorder - leftBorder > 1) return new int[]{leftBorder + 1, rightBorder - 1};
+ // 情况二
+ return new int[]{-1, -1};
+ }
+
+ int getRightBorder(int[] nums, int target) {
+ int left = 0;
+ int right = nums.length - 1;
+ int rightBorder = -2; // 记录一下rightBorder没有被赋值的情况
+ while (left <= right) {
+ int middle = left + ((right - left) / 2);
+ if (nums[middle] > target) {
+ right = middle - 1;
+ } else { // 寻找右边界,nums[middle] == target的时候更新left
+ left = middle + 1;
+ rightBorder = left;
+ }
+ }
+ return rightBorder;
+ }
+
+ int getLeftBorder(int[] nums, int target) {
+ int left = 0;
+ int right = nums.length - 1;
+ int leftBorder = -2; // 记录一下leftBorder没有被赋值的情况
+ while (left <= right) {
+ int middle = left + ((right - left) / 2);
+ if (nums[middle] >= target) { // 寻找左边界,nums[middle] == target的时候更新right
+ right = middle - 1;
+ leftBorder = right;
+ } else {
+ left = middle + 1;
+ }
+ }
+ return leftBorder;
+ }
+}
```
+```java
+// 解法2
+// 1、首先,在 nums 数组中二分查找 target;
+// 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
+// 3、如果二分查找失败,则 binarySearch 返回 nums 中 为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
+
+class Solution {
+ public int[] searchRange(int[] nums, int target) {
+ int index = binarySearch(nums, target); // 二分查找
+
+ if (index == -1) { // nums 中不存在 target,直接返回 {-1, -1}
+ return new int[] {-1, -1}; // 匿名数组
+ }
+ // nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
+ int left = index;
+ int right = index;
+ // 向左滑动,找左边界
+ while (left - 1 >= 0 && nums[left - 1] == nums[index]) { // 防止数组越界。逻辑短路,两个条件顺序不能换
+ left--;
+ }
+ // 向左滑动,找右边界
+ while (right + 1 < nums.length && nums[right + 1] == nums[index]) { // 防止数组越界。
+ right++;
+ }
+ return new int[] {left, right};
+ }
+
+ /**
+ * 二分查找
+ * @param nums
+ * @param target
+ */
+ public int binarySearch(int[] nums, int target) {
+ int left = 0;
+ int right = nums.length - 1; // 不变量:左闭右闭区间
+
+ while (left <= right) { // 不变量:左闭右闭区间
+ int mid = left + (right - left) / 2;
+ if (nums[mid] == target) {
+ return mid;
+ } else if (nums[mid] < target) {
+ left = mid + 1;
+ } else {
+ right = mid - 1; // 不变量:左闭右闭区间
+ }
+ }
+ return -1; // 不存在
+ }
+}
+```
+
+
+
## Python
```python
@@ -196,4 +293,3 @@ private:
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
-
From b6424893b3bfc25b8f4824f5ba994641e708b176 Mon Sep 17 00:00:00 2001
From: posper
Date: Wed, 28 Jul 2021 15:25:16 +0800
Subject: [PATCH 008/138] =?UTF-8?q?1207.=E7=8B=AC=E4=B8=80=E6=97=A0?=
=?UTF-8?q?=E4=BA=8C=E7=9A=84=E5=87=BA=E7=8E=B0=E6=AC=A1=E6=95=B0=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/1207.独一无二的出现次数.md | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/problems/1207.独一无二的出现次数.md b/problems/1207.独一无二的出现次数.md
index 377d9ebf..c1720430 100644
--- a/problems/1207.独一无二的出现次数.md
+++ b/problems/1207.独一无二的出现次数.md
@@ -77,6 +77,28 @@ public:
Java:
+```java
+class Solution {
+ public boolean uniqueOccurrences(int[] arr) {
+ int[] count = new int[2002];
+ for (int i = 0; i < arr.length; i++) {
+ count[arr[i] + 1000]++; // 防止负数作为下标
+ }
+ boolean[] flag = new boolean[1002]; // 标记相同频率是否重复出现
+ for (int i = 0; i <= 2000; i++) {
+ if (count[i] > 0) {
+ if (flag[count[i]] == false) {
+ flag[count[i]] = true;
+ } else {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+}
+```
+
Python:
Go:
@@ -89,4 +111,3 @@ JavaScript:
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
-
From e7f772afb4425f65d6821667ba78aa3edb52f2fc Mon Sep 17 00:00:00 2001
From: fixme
Date: Wed, 28 Jul 2021 22:49:01 +0800
Subject: [PATCH 009/138] =?UTF-8?q?=E5=A2=9E=E5=8A=A0c=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0203.移除链表元素.md | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/problems/0203.移除链表元素.md b/problems/0203.移除链表元素.md
index cac9f233..ea1d705a 100644
--- a/problems/0203.移除链表元素.md
+++ b/problems/0203.移除链表元素.md
@@ -146,8 +146,39 @@ public:
## 其他语言版本
+C:
+```c
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+struct ListNode* removeElements(struct ListNode* head, int val){
+ typedef struct ListNode ListNode;
+ ListNode *shead;
+ shead = (ListNode *)malloc(sizeof(ListNode));
+ shead->next = head;
+ ListNode *cur = shead;
+ while(cur->next != NULL){
+ if (cur->next->val == val){
+ ListNode *tmp = cur->next;
+ cur->next = cur->next->next;
+ free(tmp);
+ }
+ else{
+ cur = cur->next;
+ }
+ }
+ head = shead->next;
+ free(shead);
+ return head;
+}
+```
+
Java:
```java
/**
From c75b29bc04c71063266cfbcec97c3398e1d3ef98 Mon Sep 17 00:00:00 2001
From: kok-s0s <2694308562@qq.com>
Date: Wed, 28 Jul 2021 23:46:46 +0800
Subject: [PATCH 010/138] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E5=AE=9E=E7=8E=B0strStr()=E3=80=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0028.实现strStr.md | 86 +++++++++++++++++++++++++++++++++++++
1 file changed, 86 insertions(+)
diff --git a/problems/0028.实现strStr.md b/problems/0028.实现strStr.md
index 69f8c9d6..fc14a34a 100644
--- a/problems/0028.实现strStr.md
+++ b/problems/0028.实现strStr.md
@@ -808,7 +808,93 @@ func strStr(haystack string, needle string) int {
}
```
+JavaScript版本
+> 前缀表统一减一
+
+```javascript
+/**
+ * @param {string} haystack
+ * @param {string} needle
+ * @return {number}
+ */
+var strStr = function (haystack, needle) {
+ if (needle.length === 0)
+ return 0;
+
+ const getNext = (needle) => {
+ let next = [];
+ let j = -1;
+ next.push(j);
+
+ for (let i = 1; i < needle.length; ++i) {
+ while (j >= 0 && needle[i] !== needle[j + 1])
+ j = next[j];
+ if (needle[i] === needle[j + 1])
+ j++;
+ next.push(j);
+ }
+
+ return next;
+ }
+
+ let next = getNext(needle);
+ let j = -1;
+ for (let i = 0; i < haystack.length; ++i) {
+ while (j >= 0 && haystack[i] !== needle[j + 1])
+ j = next[j];
+ if (haystack[i] === needle[j + 1])
+ j++;
+ if (j === needle.length - 1)
+ return (i - needle.length + 1);
+ }
+
+ return -1;
+};
+```
+
+> 前缀表统一不减一
+
+```javascript
+/**
+ * @param {string} haystack
+ * @param {string} needle
+ * @return {number}
+ */
+var strStr = function (haystack, needle) {
+ if (needle.length === 0)
+ return 0;
+
+ const getNext = (needle) => {
+ let next = [];
+ let j = 0;
+ next.push(j);
+
+ for (let i = 1; i < needle.length; ++i) {
+ while (j > 0 && needle[i] !== needle[j])
+ j = next[j - 1];
+ if (needle[i] === needle[j])
+ j++;
+ next.push(j);
+ }
+
+ return next;
+ }
+
+ let next = getNext(needle);
+ let j = 0;
+ for (let i = 0; i < haystack.length; ++i) {
+ while (j > 0 && haystack[i] !== needle[j])
+ j = next[j - 1];
+ if (haystack[i] === needle[j])
+ j++;
+ if (j === needle.length)
+ return (i - needle.length + 1);
+ }
+
+ return -1;
+};
+```
From 3dcaa43ffe0e6b585e0eb2c372ea7786c1e7cca6 Mon Sep 17 00:00:00 2001
From: kok-s0s <2694308562@qq.com>
Date: Wed, 28 Jul 2021 23:48:27 +0800
Subject: [PATCH 011/138] =?UTF-8?q?=E6=8F=90=E4=BE=9BJavaScript=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E7=9A=84=E3=80=8A=E9=87=8D=E5=A4=8D=E7=9A=84=E5=AD=90?=
=?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2=E3=80=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0459.重复的子字符串.md | 71 +++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/problems/0459.重复的子字符串.md b/problems/0459.重复的子字符串.md
index f012811d..25b52e86 100644
--- a/problems/0459.重复的子字符串.md
+++ b/problems/0459.重复的子字符串.md
@@ -289,8 +289,79 @@ func repeatedSubstringPattern(s string) bool {
}
```
+JavaScript版本
+> 前缀表统一减一
+```javascript
+/**
+ * @param {string} s
+ * @return {boolean}
+ */
+var repeatedSubstringPattern = function (s) {
+ if (s.length === 0)
+ return false;
+
+ const getNext = (s) => {
+ let next = [];
+ let j = -1;
+
+ next.push(j);
+
+ for (let i = 1; i < s.length; ++i) {
+ while (j >= 0 && s[i] !== s[j + 1])
+ j = next[j];
+ if (s[i] === s[j + 1])
+ j++;
+ next.push(j);
+ }
+
+ return next;
+ }
+
+ let next = getNext(s);
+
+ if (next[next.length - 1] !== -1 && s.length % (s.length - (next[next.length - 1] + 1)) === 0)
+ return true;
+ return false;
+};
+```
+
+> 前缀表统一不减一
+
+```javascript
+/**
+ * @param {string} s
+ * @return {boolean}
+ */
+var repeatedSubstringPattern = function (s) {
+ if (s.length === 0)
+ return false;
+
+ const getNext = (s) => {
+ let next = [];
+ let j = 0;
+
+ next.push(j);
+
+ for (let i = 1; i < s.length; ++i) {
+ while (j > 0 && s[i] !== s[j])
+ j = next[j - 1];
+ if (s[i] === s[j])
+ j++;
+ next.push(j);
+ }
+
+ return next;
+ }
+
+ let next = getNext(s);
+
+ if (next[next.length - 1] !== 0 && s.length % (s.length - next[next.length - 1]) === 0)
+ return true;
+ return false;
+};
+```
From 31c9f09776b9ef6bf9e7861a32a43fde571fdcbf Mon Sep 17 00:00:00 2001
From: reoooh
Date: Wed, 28 Jul 2021 23:57:26 +0800
Subject: [PATCH 012/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A00704=E4=BA=8C?=
=?UTF-8?q?=E5=88=86=E6=9F=A5=E6=89=BE=20Ruby=20=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0704.二分查找.md | 42 ++++++++++++++++++++++++++++++++++++---
1 file changed, 39 insertions(+), 3 deletions(-)
diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md
index cce471ae..66be52a0 100644
--- a/problems/0704.二分查找.md
+++ b/problems/0704.二分查找.md
@@ -235,8 +235,6 @@ class Solution:
return -1
```
-
-
**Go:**
(版本一)左闭右闭区间
@@ -279,7 +277,7 @@ func search(nums []int, target int) int {
}
```
-**javaScript:**
+**JavaScript:**
```js
@@ -316,7 +314,45 @@ var search = function(nums, target) {
```
+**Ruby:**
+```ruby
+# (版本一)左闭右闭区间
+
+def search(nums, target)
+ left, right = 0, nums.length - 1
+ while left <= right # 由于定义target在一个在左闭右闭的区间里,因此极限情况下存在left==right
+ middle = (left + right) / 2
+ if nums[middle] > target
+ right = middle - 1
+ elsif nums[middle] < target
+ left = middle + 1
+ else
+ return middle # return兼具返回与跳出循环的作用
+ end
+ end
+ -1
+end
+
+# (版本二)左闭右开区间
+
+def search(nums, target)
+ left, right = 0, nums.length - 1
+ while left < right # 由于定义target在一个在左闭右开的区间里,因此极限情况下right=left+1
+ middle = (left + right) / 2
+ if nums[middle] > target
+ right = middle
+ elsif nums[middle] < target
+ left = middle + 1
+ else
+ return middle
+ end
+ end
+ -1
+end
+
+p search(nums,target)
+```
From 4fcb27c7cf827d0c13bc261c4374cb5b199cbf1d Mon Sep 17 00:00:00 2001
From: reoooh
Date: Thu, 29 Jul 2021 00:07:44 +0800
Subject: [PATCH 013/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A00704=E4=BA=8C?=
=?UTF-8?q?=E5=88=86=E6=9F=A5=E6=89=BE=20Ruby=20=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0704.二分查找.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md
index 66be52a0..caec38b1 100644
--- a/problems/0704.二分查找.md
+++ b/problems/0704.二分查找.md
@@ -337,7 +337,7 @@ end
# (版本二)左闭右开区间
def search(nums, target)
- left, right = 0, nums.length - 1
+ left, right = 0, nums.length
while left < right # 由于定义target在一个在左闭右开的区间里,因此极限情况下right=left+1
middle = (left + right) / 2
if nums[middle] > target
From 2c7ea5a9f595acbebf03ba656d72ecc2b65d6a88 Mon Sep 17 00:00:00 2001
From: jiangjiang <366649270@qq.com>
Date: Thu, 29 Jul 2021 00:46:31 +0800
Subject: [PATCH 014/138] =?UTF-8?q?Update=200053.=E6=9C=80=E5=A4=A7?=
=?UTF-8?q?=E5=AD=90=E5=BA=8F=E5=92=8C=EF=BC=88=E5=8A=A8=E6=80=81=E8=A7=84?=
=?UTF-8?q?=E5=88=92=EF=BC=89.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
add solution of golang for 0053.最大子序和
---
problems/0053.最大子序和(动态规划).md | 28 +++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/problems/0053.最大子序和(动态规划).md b/problems/0053.最大子序和(动态规划).md
index dd0e513b..ada378b2 100644
--- a/problems/0053.最大子序和(动态规划).md
+++ b/problems/0053.最大子序和(动态规划).md
@@ -138,7 +138,35 @@ class Solution:
```
Go:
+```Go
+// solution
+// 1, dp
+// 2, 贪心
+func maxSubArray(nums []int) int {
+ n := len(nums)
+ // 这里的dp[i] 表示,最大的连续子数组和,包含num[i] 元素
+ dp := make([]int,n)
+ // 初始化,由于dp 状态转移方程依赖dp[0]
+ dp[0] = nums[0]
+ // 初始化最大的和
+ mx := nums[0]
+ for i:=1;ib {
+ return a
+ }
+ return b
+}
+```
From 57eba785b01cd2ea8cd2fea175def72b20b18291 Mon Sep 17 00:00:00 2001
From: youngyangyang04 <826123027@qq.com>
Date: Thu, 29 Jul 2021 10:31:40 +0800
Subject: [PATCH 015/138] Update
---
README.md | 1 -
...034.在排序数组中查找元素的第一个和最后一个位置.md | 4 ++--
.../通过一道面试题目,讲一讲递归算法的时间复杂度!.md | 12 +++++-------
3 files changed, 7 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index c006fd6b..bbceda2e 100644
--- a/README.md
+++ b/README.md
@@ -451,7 +451,6 @@
* [24.两两交换链表中的节点](./problems/0024.两两交换链表中的节点.md)
* [234.回文链表](./problems/0234.回文链表.md)
* [143.重排链表](./problems/0143.重排链表.md)【数组】【双向队列】【直接操作链表】
-* [234.回文链表](./problems/0234.回文链表.md)
* [141.环形链表](./problems/0141.环形链表.md)
## 哈希表
diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
index 04f5eaf7..0322ec59 100644
--- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
+++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
@@ -56,9 +56,9 @@
## 寻找右边界
-先来寻找右边界,至于二分查找,如果看过[为什么每次遇到二分法,都是一看就会,一写就废](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q)就会知道,二分查找中什么时候用while (left <= right),有什么时候用while (left < right),其实只要清楚**循环不变量**,很容易区分两种写法。
+先来寻找右边界,至于二分查找,如果看过[704.二分查找](https://mp.weixin.qq.com/s/4X-8VRgnYRGd5LYGZ33m4w)就会知道,二分查找中什么时候用while (left <= right),有什么时候用while (left < right),其实只要清楚**循环不变量**,很容易区分两种写法。
-那么这里我采用while (left <= right)的写法,区间定义为[left, right],即左闭又闭的区间(如果这里有点看不懂了,强烈建议把[为什么每次遇到二分法,都是一看就会,一写就废](https://mp.weixin.qq.com/s/fCf5QbPDtE6SSlZ1yh_q8Q)这篇文章先看了,在把「leetcode:35.搜索插入位置」做了之后在做这道题目就好很多了)
+那么这里我采用while (left <= right)的写法,区间定义为[left, right],即左闭又闭的区间(如果这里有点看不懂了,强烈建议把[704.二分查找](https://mp.weixin.qq.com/s/4X-8VRgnYRGd5LYGZ33m4w)这篇文章先看了,704题目做了之后再做这道题目就好很多了)
确定好:计算出来的右边界是不包好target的右边界,左边界同理。
diff --git a/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md b/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md
index 16ba8361..5a75b6c7 100644
--- a/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md
+++ b/problems/前序/通过一道面试题目,讲一讲递归算法的时间复杂度!.md
@@ -44,7 +44,7 @@ int function1(int x, int n) {
那么就可以写出了如下这样的一个递归的算法,使用递归解决了这个问题。
-```
+```C++
int function2(int x, int n) {
if (n == 0) {
return 1; // return 1 同样是因为0次方是等于1的
@@ -62,7 +62,7 @@ int function2(int x, int n) {
这个时间复杂度就没有达到面试官的预期。于是又写出了如下的递归算法的代码:
-```
+```C++
int function3(int x, int n) {
if (n == 0) {
return 1;
@@ -101,7 +101,7 @@ int function3(int x, int n) {
于是又写出如下递归算法的代码:
-```
+```C++
int function4(int x, int n) {
if (n == 0) {
return 1;
@@ -132,7 +132,7 @@ int function4(int x, int n) {
对于function3 这样的递归实现,很容易让人感觉这是O(logn)的时间复杂度,其实这是O(n)的算法!
-```
+```C++
int function3(int x, int n) {
if (n == 0) {
return 1;
@@ -145,14 +145,12 @@ int function3(int x, int n) {
```
可以看出这道题目非常简单,但是又很考究算法的功底,特别是对递归的理解,这也是我面试别人的时候用过的一道题,所以整个情景我才写的如此逼真,哈哈。
-大厂面试的时候最喜欢用“简单题”来考察候选人的算法功底,注意这里的“简单题”可并不一定真的简单哦!
+大厂面试的时候最喜欢用“简单题”来考察候选人的算法功底,注意这里的“简单题”可并不一定真的简单哦!
如果认真读完本篇,相信大家对递归算法的有一个新的认识的,同一道题目,同样是递归,效率可是不一样的!
-
-
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
From 39f313ff0cec5c1ca94d56116a6b78f15882a56a Mon Sep 17 00:00:00 2001
From: wjjiang <48505670+Spongecaptain@users.noreply.github.com>
Date: Thu, 29 Jul 2021 11:44:51 +0800
Subject: [PATCH 016/138] =?UTF-8?q?Update=20=E4=BA=8C=E5=8F=89=E6=A0=91?=
=?UTF-8?q?=E7=9A=84=E9=80=92=E5=BD=92=E9=81=8D=E5=8E=86.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Go 中函数应该为小写 与 leetcode 保持一致。
---
problems/二叉树的递归遍历.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/problems/二叉树的递归遍历.md b/problems/二叉树的递归遍历.md
index 2b5a44dd..220ccf65 100644
--- a/problems/二叉树的递归遍历.md
+++ b/problems/二叉树的递归遍历.md
@@ -222,7 +222,7 @@ Go:
前序遍历:
```go
-func PreorderTraversal(root *TreeNode) (res []int) {
+func preorderTraversal(root *TreeNode) (res []int) {
var traversal func(node *TreeNode)
traversal = func(node *TreeNode) {
if node == nil {
@@ -240,7 +240,7 @@ func PreorderTraversal(root *TreeNode) (res []int) {
中序遍历:
```go
-func InorderTraversal(root *TreeNode) (res []int) {
+func inorderTraversal(root *TreeNode) (res []int) {
var traversal func(node *TreeNode)
traversal = func(node *TreeNode) {
if node == nil {
@@ -257,7 +257,7 @@ func InorderTraversal(root *TreeNode) (res []int) {
后序遍历:
```go
-func PostorderTraversal(root *TreeNode) (res []int) {
+func postorderTraversal(root *TreeNode) (res []int) {
var traversal func(node *TreeNode)
traversal = func(node *TreeNode) {
if node == nil {
From 7029cf6b6eb760df09d39ce9a399f34016682ccf Mon Sep 17 00:00:00 2001
From: reoooh
Date: Thu, 29 Jul 2021 13:49:02 +0800
Subject: [PATCH 017/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A00704=E4=BA=8C?=
=?UTF-8?q?=E5=88=86=E6=9F=A5=E6=89=BE=20Ruby=20=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0704.二分查找.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md
index caec38b1..ed0e2eed 100644
--- a/problems/0704.二分查找.md
+++ b/problems/0704.二分查找.md
@@ -350,8 +350,6 @@ def search(nums, target)
end
-1
end
-
-p search(nums,target)
```
From e9c5f17af52cbeee408e349d7a7655b5d711bc80 Mon Sep 17 00:00:00 2001
From: posper
Date: Thu, 29 Jul 2021 18:48:56 +0800
Subject: [PATCH 018/138] =?UTF-8?q?724.=E5=AF=BB=E6=89=BE=E6=95=B0?=
=?UTF-8?q?=E7=BB=84=E7=9A=84=E4=B8=AD=E5=BF=83=E4=B8=8B=E6=A0=87=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0724.寻找数组的中心索引.md | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/problems/0724.寻找数组的中心索引.md b/problems/0724.寻找数组的中心索引.md
index bf989979..09966e05 100644
--- a/problems/0724.寻找数组的中心索引.md
+++ b/problems/0724.寻找数组的中心索引.md
@@ -67,6 +67,24 @@ public:
## Java
```java
+class Solution {
+ public int pivotIndex(int[] nums) {
+ int sum = 0;
+ for (int i = 0; i < nums.length; i++) {
+ sum += nums[i]; // 总和
+ }
+ int leftSum = 0;
+ int rightSum = 0;
+ for (int i = 0; i < nums.length; i++) {
+ leftSum += nums[i];
+ rightSum = sum - leftSum + nums[i]; // leftSum 里面已经有 nums[i],多减了一次,所以加上
+ if (leftSum == rightSum) {
+ return i;
+ }
+ }
+ return -1; // 不存在
+ }
+}
```
## Python
@@ -90,4 +108,3 @@ public:
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
-
From 3fd951ef5fec91b3dc9be7e57aa76daf83c35f87 Mon Sep 17 00:00:00 2001
From: posper
Date: Thu, 29 Jul 2021 18:56:15 +0800
Subject: [PATCH 019/138] =?UTF-8?q?922.=20=E6=8C=89=E5=A5=87=E5=81=B6?=
=?UTF-8?q?=E6=8E=92=E5=BA=8F=E6=95=B0=E7=BB=84II=20=E6=B7=BB=E5=8A=A0Java?=
=?UTF-8?q?=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0922.按奇偶排序数组II.md | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/problems/0922.按奇偶排序数组II.md b/problems/0922.按奇偶排序数组II.md
index bb609c12..d4c1be7a 100644
--- a/problems/0922.按奇偶排序数组II.md
+++ b/problems/0922.按奇偶排序数组II.md
@@ -120,6 +120,31 @@ public:
## Java
```java
+// 方法一
+class Solution {
+ public int[] sortArrayByParityII(int[] nums) {
+ // 分别存放 nums 中的奇数、偶数
+ int len = nums.length;
+ int evenIndex = 0;
+ int oddIndex = 0;
+ int[] even = new int[len / 2];
+ int[] odd = new int[len / 2];
+ for (int i = 0; i < len; i++) {
+ if (nums[i] % 2 == 0) {
+ even[evenIndex++] = nums[i];
+ } else {
+ odd[oddIndex++] = nums[i];
+ }
+ }
+ // 把奇偶数组重新存回 nums
+ int index = 0;
+ for (int i = 0; i < even.length; i++) {
+ nums[index++] = even[i];
+ nums[index++] = odd[i];
+ }
+ return nums;
+ }
+}
```
## Python
@@ -143,4 +168,3 @@ public:
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
-
From d8247fe8499f14497972fc32456f752a7bf6d574 Mon Sep 17 00:00:00 2001
From: posper
Date: Thu, 29 Jul 2021 19:22:47 +0800
Subject: [PATCH 020/138] =?UTF-8?q?844.=E6=AF=94=E8=BE=83=E5=90=AB?=
=?UTF-8?q?=E9=80=80=E6=A0=BC=E7=9A=84=E5=AD=97=E7=AC=A6=E4=B8=B2=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0844.比较含退格的字符串.md | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/problems/0844.比较含退格的字符串.md b/problems/0844.比较含退格的字符串.md
index 9f37959d..4b4ff63b 100644
--- a/problems/0844.比较含退格的字符串.md
+++ b/problems/0844.比较含退格的字符串.md
@@ -14,7 +14,7 @@
给定 S 和 T 两个字符串,当它们分别被输入到空白的文本编辑器后,判断二者是否相等,并返回结果。 # 代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
-
+
示例 1:
* 输入:S = "ab#c", T = "ad#c"
* 输出:true
@@ -160,6 +160,32 @@ public:
Java:
+```java
+// 普通方法(使用栈的思路)
+class Solution {
+ public boolean backspaceCompare(String s, String t) {
+ StringBuilder ssb = new StringBuilder(); // 模拟栈
+ StringBuilder tsb = new StringBuilder(); // 模拟栈
+ // 分别处理两个 String
+ for (char c : s.toCharArray()) {
+ if (c != '#') {
+ ssb.append(c); // 模拟入栈
+ } else if (ssb.length() > 0){ // 栈非空才能弹栈
+ ssb.deleteCharAt(ssb.length() - 1); // 模拟弹栈
+ }
+ }
+ for (char c : t.toCharArray()) {
+ if (c != '#') {
+ tsb.append(c); // 模拟入栈
+ } else if (tsb.length() > 0){ // 栈非空才能弹栈
+ tsb.deleteCharAt(tsb.length() - 1); // 模拟弹栈
+ }
+ }
+ return ssb.toString().equals(tsb.toString());
+ }
+}
+```
+
Python:
Go:
From a6a8650b8a6524ed03cf599f1c32fc42c78cd8e5 Mon Sep 17 00:00:00 2001
From: posper
Date: Thu, 29 Jul 2021 19:32:33 +0800
Subject: [PATCH 021/138] =?UTF-8?q?205.=E5=90=8C=E6=9E=84=E5=AD=97?=
=?UTF-8?q?=E7=AC=A6=E4=B8=B2=20=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0205.同构字符串.md | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/problems/0205.同构字符串.md b/problems/0205.同构字符串.md
index 4e963ece..06ea5701 100644
--- a/problems/0205.同构字符串.md
+++ b/problems/0205.同构字符串.md
@@ -68,6 +68,25 @@ public:
## Java
```java
+class Solution {
+ public boolean isIsomorphic(String s, String t) {
+ Map map1 = new HashMap<>();
+ Map map2 = new HashMap<>();
+ for (int i = 0, j = 0; i < s.length(); i++, j++) {
+ if (!map1.containsKey(s.charAt(i))) {
+ map1.put(s.charAt(i), t.charAt(j)); // map1保存 s[i] 到 t[j]的映射
+ }
+ if (!map2.containsKey(t.charAt(j))) {
+ map2.put(t.charAt(j), s.charAt(i)); // map1保存 t[j] 到 s[i]的映射
+ }
+ // 无法映射,返回 false
+ if (map1.get(s.charAt(i)) != t.charAt(j) || map2.get(t.charAt(j)) != s.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
```
## Python
From 9e08c0e5de17773b345f0cc59fb661b333bd946f Mon Sep 17 00:00:00 2001
From: posper
Date: Thu, 29 Jul 2021 19:36:37 +0800
Subject: [PATCH 022/138] =?UTF-8?q?205.=E5=90=8C=E6=9E=84=E5=AD=97?=
=?UTF-8?q?=E7=AC=A6=E4=B8=B2=20=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
=?UTF-8?q?=EF=BC=88=E6=B3=A8=E9=87=8A=E4=BF=AE=E6=94=B9=EF=BC=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0205.同构字符串.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/problems/0205.同构字符串.md b/problems/0205.同构字符串.md
index 06ea5701..7ffa3fbf 100644
--- a/problems/0205.同构字符串.md
+++ b/problems/0205.同构字符串.md
@@ -77,7 +77,7 @@ class Solution {
map1.put(s.charAt(i), t.charAt(j)); // map1保存 s[i] 到 t[j]的映射
}
if (!map2.containsKey(t.charAt(j))) {
- map2.put(t.charAt(j), s.charAt(i)); // map1保存 t[j] 到 s[i]的映射
+ map2.put(t.charAt(j), s.charAt(i)); // map2保存 t[j] 到 s[i]的映射
}
// 无法映射,返回 false
if (map1.get(s.charAt(i)) != t.charAt(j) || map2.get(t.charAt(j)) != s.charAt(i)) {
From 1521e4016537243bd2a6d5898f2099e53f588d42 Mon Sep 17 00:00:00 2001
From: posper
Date: Thu, 29 Jul 2021 20:00:16 +0800
Subject: [PATCH 023/138] =?UTF-8?q?31.=E4=B8=8B=E4=B8=80=E4=B8=AA=E6=8E=92?=
=?UTF-8?q?=E5=88=97=20=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0031.下一个排列.md | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/problems/0031.下一个排列.md b/problems/0031.下一个排列.md
index fbe31eb3..53e6644d 100644
--- a/problems/0031.下一个排列.md
+++ b/problems/0031.下一个排列.md
@@ -99,6 +99,24 @@ public:
## Java
```java
+class Solution {
+ public void nextPermutation(int[] nums) {
+ for (int i = nums.length - 1; i >= 0; i--) {
+ for (int j = nums.length - 1; j > i; j--) {
+ if (nums[j] > nums[i]) {
+ // 交换
+ int temp = nums[i];
+ nums[i] = nums[j];
+ nums[j] = temp;
+ // [i + 1, nums.length) 内元素升序排序
+ Arrays.sort(nums, i + 1, nums.length);
+ return;
+ }
+ }
+ }
+ Arrays.sort(nums); // 不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
+ }
+}
```
## Python
From 0b2312ffec67c90a53feb938a6df5444c41fbc1a Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Thu, 29 Jul 2021 09:02:15 -0400
Subject: [PATCH 024/138] =?UTF-8?q?Update=200404.=E5=B7=A6=E5=8F=B6?=
=?UTF-8?q?=E5=AD=90=E4=B9=8B=E5=92=8C.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
添加python3 迭代方法的代码.
Q: 我为什么要更改当前已有的递归代码?
A: 因为我发现当前版本的递归代码跟Carl哥的逻辑不是特别一样. 我承认解题思路千变万化, 但是个人感觉最好最好还是尽量跟Carl的思路一样, 这样方便初学者阅读不同语言编写出来的代码.
---
problems/0404.左叶子之和.md | 56 +++++++++++++++++++++++++++----------
1 file changed, 41 insertions(+), 15 deletions(-)
diff --git a/problems/0404.左叶子之和.md b/problems/0404.左叶子之和.md
index aa758367..2a76a461 100644
--- a/problems/0404.左叶子之和.md
+++ b/problems/0404.左叶子之和.md
@@ -205,25 +205,51 @@ 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
+```python
class Solution:
def sumOfLeftLeaves(self, root: TreeNode) -> int:
- self.res=0
- def areleftleaves(root):
- if not root:return
- if root.left and (not root.left.left) and (not root.left.right):self.res+=root.left.val
- areleftleaves(root.left)
- areleftleaves(root.right)
- areleftleaves(root)
- return self.res
+ if not root:
+ return 0
+
+ left_left_leaves_sum = self.sumOfLeftLeaves(root.left) # 左
+ right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右
+
+ cur_left_leaf_val = 0
+ if root.left and not root.left.left and not root.left.right:
+ cur_left_leaf_val = root.left.val # 中
+
+ return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum
```
+
+**迭代**
+```python
+class Solution:
+ def sumOfLeftLeaves(self, root: TreeNode) -> int:
+ """
+ Idea: Each time check current node's left node.
+ If current node don't have one, skip it.
+ """
+ stack = []
+ if root:
+ stack.append(root)
+ res = 0
+
+ while stack:
+ # 每次都把当前节点的左节点加进去.
+ cur_node = stack.pop()
+ if cur_node.left and not cur_node.left.left and not cur_node.left.right:
+ res += cur_node.left.val
+
+ if cur_node.left:
+ stack.append(cur_node.left)
+ if cur_node.right:
+ stack.append(cur_node.right)
+
+ return res
+```
+
Go:
> 递归法
From 2f412e5c7d3b41b66946d92e699330cb7e5e5036 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Thu, 29 Jul 2021 11:18:26 -0400
Subject: [PATCH 025/138] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20513.=E6=89=BE?=
=?UTF-8?q?=E6=A0=91=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC=20python?=
=?UTF-8?q?=20=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 更改python 递归代码: 上一版本python代码跟卡哥思路不一样, 感觉把不同的解题方法放在这里不方便初学者学习. 所以建议更改.
2. 添加迭代方法代码.
---
problems/0513.找树左下角的值.md | 61 ++++++++++++++++++++++++++-------
1 file changed, 49 insertions(+), 12 deletions(-)
diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md
index 17d15fde..391118ab 100644
--- a/problems/0513.找树左下角的值.md
+++ b/problems/0513.找树左下角的值.md
@@ -274,8 +274,9 @@ class Solution {
Python:
+
+**递归法 - 回溯**
```python
-//递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
@@ -284,17 +285,53 @@ Python:
# self.right = right
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
- depth=0
- self.res=[]
- def level(root,depth):
- if not root:return
- if depth==len(self.res):
- self.res.append([])
- self.res[depth].append(root.val)
- level(root.left,depth+1)
- level(root.right,depth+1)
- level(root,depth)
- return self.res[-1][0]
+ max_depth = -float("INF")
+ max_left_value = -float("INF")
+
+ def __traversal(root, left_len):
+ nonlocal max_depth, max_left_value
+
+ if not root.left and not root.right:
+ if left_len > max_depth:
+ max_depth = left_len
+ max_left_value = root.val
+ return
+
+ if root.left:
+ left_len += 1
+ __traversal(root.left, left_len)
+ left_len -= 1
+
+ if root.right:
+ left_len += 1
+ __traversal(root.right, left_len)
+ left_len -= 1
+ return
+
+ __traversal(root, 0)
+
+ return max_left_value
+```
+
+**迭代法 - 层序遍历**
+```python
+class Solution:
+ def findBottomLeftValue(self, root: TreeNode) -> int:
+ queue = deque()
+ if root:
+ queue.append(root)
+ result = 0
+ while queue:
+ q_len = len(queue)
+ for i in range(q_len):
+ if i == 0:
+ result = queue[i].val
+ cur = queue.popleft()
+ if cur.left:
+ queue.append(cur.left)
+ if cur.right:
+ queue.append(cur.right)
+ return result
```
Go:
From 8c53c48ea87fc2f02934799da6f659a7647eb268 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Thu, 29 Jul 2021 11:21:14 -0400
Subject: [PATCH 026/138] =?UTF-8?q?Revert=20"=E6=9B=B4=E6=96=B0=20513.?=
=?UTF-8?q?=E6=89=BE=E6=A0=91=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC?=
=?UTF-8?q?=20python=20=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This reverts commit 2f412e5c7d3b41b66946d92e699330cb7e5e5036.
---
problems/0513.找树左下角的值.md | 61 +++++++--------------------------
1 file changed, 12 insertions(+), 49 deletions(-)
diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md
index 391118ab..17d15fde 100644
--- a/problems/0513.找树左下角的值.md
+++ b/problems/0513.找树左下角的值.md
@@ -274,9 +274,8 @@ class Solution {
Python:
-
-**递归法 - 回溯**
```python
+//递归法
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
@@ -285,53 +284,17 @@ Python:
# self.right = right
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
- max_depth = -float("INF")
- max_left_value = -float("INF")
-
- def __traversal(root, left_len):
- nonlocal max_depth, max_left_value
-
- if not root.left and not root.right:
- if left_len > max_depth:
- max_depth = left_len
- max_left_value = root.val
- return
-
- if root.left:
- left_len += 1
- __traversal(root.left, left_len)
- left_len -= 1
-
- if root.right:
- left_len += 1
- __traversal(root.right, left_len)
- left_len -= 1
- return
-
- __traversal(root, 0)
-
- return max_left_value
-```
-
-**迭代法 - 层序遍历**
-```python
-class Solution:
- def findBottomLeftValue(self, root: TreeNode) -> int:
- queue = deque()
- if root:
- queue.append(root)
- result = 0
- while queue:
- q_len = len(queue)
- for i in range(q_len):
- if i == 0:
- result = queue[i].val
- cur = queue.popleft()
- if cur.left:
- queue.append(cur.left)
- if cur.right:
- queue.append(cur.right)
- return result
+ depth=0
+ self.res=[]
+ def level(root,depth):
+ if not root:return
+ if depth==len(self.res):
+ self.res.append([])
+ self.res[depth].append(root.val)
+ level(root.left,depth+1)
+ level(root.right,depth+1)
+ level(root,depth)
+ return self.res[-1][0]
```
Go:
From 49d55fb1c8c26f668c1676075ac10a21b527ab92 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Thu, 29 Jul 2021 11:25:33 -0400
Subject: [PATCH 027/138] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20513.=E6=89=BE?=
=?UTF-8?q?=E6=A0=91=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC=20python?=
=?UTF-8?q?=E9=83=A8=E5=88=86=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 上一版本 递归python代码跟题解的方式不同. 个人认为不同方法做出的代码没有必要放在题解里, 建议修改成我提供的python版本.
2. 增加Python3 迭代部分的代码.
---
problems/0513.找树左下角的值.md | 66 ++++++++++++++++++++++++---------
1 file changed, 48 insertions(+), 18 deletions(-)
diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md
index 17d15fde..e83fcc18 100644
--- a/problems/0513.找树左下角的值.md
+++ b/problems/0513.找树左下角的值.md
@@ -274,27 +274,57 @@ 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:
def findBottomLeftValue(self, root: TreeNode) -> int:
- depth=0
- self.res=[]
- def level(root,depth):
- if not root:return
- if depth==len(self.res):
- self.res.append([])
- self.res[depth].append(root.val)
- level(root.left,depth+1)
- level(root.right,depth+1)
- level(root,depth)
- return self.res[-1][0]
+ max_depth = -float("INF")
+ max_left_value = -float("INF")
+
+ def __traversal(root, left_len):
+ nonlocal max_depth, max_left_value
+
+ if not root.left and not root.right:
+ if left_len > max_depth:
+ max_depth = left_len
+ max_left_value = root.val
+ return
+
+ if root.left:
+ left_len += 1
+ __traversal(root.left, left_len)
+ left_len -= 1
+
+ if root.right:
+ left_len += 1
+ __traversal(root.right, left_len)
+ left_len -= 1
+ return
+
+ __traversal(root, 0)
+
+ return max_left_value
+```
+**迭代 - 层序遍历**
+```python
+class Solution:
+ def findBottomLeftValue(self, root: TreeNode) -> int:
+ queue = deque()
+ if root:
+ queue.append(root)
+ result = 0
+ while queue:
+ q_len = len(queue)
+ for i in range(q_len):
+ if i == 0:
+ result = queue[i].val
+ cur = queue.popleft()
+ if cur.left:
+ queue.append(cur.left)
+ if cur.right:
+ queue.append(cur.right)
+ return result
```
Go:
From 1dd4a529fcc7e7d9fb2de170fbd628d9f2af6f7f Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Thu, 29 Jul 2021 13:50:56 -0400
Subject: [PATCH 028/138] =?UTF-8?q?Update=200513.=E6=89=BE=E6=A0=91?=
=?UTF-8?q?=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
更改变量名称
---
problems/0513.找树左下角的值.md | 34 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 20 deletions(-)
diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md
index e83fcc18..27c6e83c 100644
--- a/problems/0513.找树左下角的值.md
+++ b/problems/0513.找树左下角的值.md
@@ -280,31 +280,25 @@ Python:
class Solution:
def findBottomLeftValue(self, root: TreeNode) -> int:
max_depth = -float("INF")
- max_left_value = -float("INF")
-
- def __traversal(root, left_len):
- nonlocal max_depth, max_left_value
+ leftmost_val = 0
+ def __traverse(root, cur_depth):
+ nonlocal max_depth, leftmost_val
if not root.left and not root.right:
- if left_len > max_depth:
- max_depth = left_len
- max_left_value = root.val
- return
-
+ if cur_depth > max_depth:
+ max_depth = cur_depth
+ leftmost_val = root.val
if root.left:
- left_len += 1
- __traversal(root.left, left_len)
- left_len -= 1
-
+ cur_depth += 1
+ __traverse(root.left, cur_depth)
+ cur_depth -= 1
if root.right:
- left_len += 1
- __traversal(root.right, left_len)
- left_len -= 1
- return
-
- __traversal(root, 0)
+ cur_depth += 1
+ __traverse(root.right, cur_depth)
+ cur_depth -= 1
- return max_left_value
+ __traverse(root, 0)
+ return leftmost_val
```
**迭代 - 层序遍历**
```python
From 440e04fffe7bc5cfacd11653fc6f0d3704382767 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Thu, 29 Jul 2021 15:50:46 -0400
Subject: [PATCH 029/138] =?UTF-8?q?=E6=9B=B4=E6=94=B9=200112.=E8=B7=AF?=
=?UTF-8?q?=E5=BE=84=E6=80=BB=E5=92=8C.md=20Python3=20=E4=BB=A3=E7=A0=81.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
0112.路径总和:
1. 修改了 python3 注释, 更改代码格式.
2. 增加了迭代方法Python3代码.
0113.路径总和-ii:
上一版python3代码的问题: (1)注释一般不用// (2)代码格式有些不规范. (3)内层函数命名也不是特别的informative.
新版本代码修改了上述问题.
本次提交代码均已通过leetcode测试.
---
problems/0112.路径总和.md | 113 ++++++++++++++++++++++++--------------
1 file changed, 72 insertions(+), 41 deletions(-)
diff --git a/problems/0112.路径总和.md b/problems/0112.路径总和.md
index ae9a9267..474e17da 100644
--- a/problems/0112.路径总和.md
+++ b/problems/0112.路径总和.md
@@ -416,6 +416,8 @@ class Solution {
Python:
0112.路径总和
+
+**递归**
```python
# Definition for a binary tree node.
# class TreeNode:
@@ -424,28 +426,56 @@ Python:
# self.left = left
# self.right = right
-// 递归法
-
class Solution:
def hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
- def isornot(root,targetSum)->bool:
- if (not root.left) and (not root.right) and targetSum == 0:return True // 遇到叶子节点,并且计数为0
- if (not root.left) and (not root.right):return False //遇到叶子节点,计数不为0
+ def isornot(root, targetSum) -> bool:
+ if (not root.left) and (not root.right) and targetSum == 0:
+ return True # 遇到叶子节点,并且计数为0
+ if (not root.left) and (not root.right):
+ return False # 遇到叶子节点,计数不为0
if root.left:
- targetSum -= root.left.val //左节点
- if isornot(root.left,targetSum):return True //递归,处理左节点
- targetSum += root.left.val //回溯
+ targetSum -= root.left.val # 左节点
+ if isornot(root.left, targetSum): return True # 递归,处理左节点
+ targetSum += root.left.val # 回溯
if root.right:
- targetSum -= root.right.val //右节点
- if isornot(root.right,targetSum):return True //递归,处理右节点
- targetSum += root.right.val //回溯
+ targetSum -= root.right.val # 右节点
+ if isornot(root.right, targetSum): return True # 递归,处理右节点
+ targetSum += root.right.val # 回溯
return False
-
- if root == None:return False //别忘记处理空TreeNode
- else:return isornot(root,targetSum-root.val)
+
+ if root == None:
+ return False # 别忘记处理空TreeNode
+ else:
+ return isornot(root, targetSum - root.val)
```
+**迭代 - 层序遍历**
+```python
+class Solution:
+ def hasPathSum(self, root: TreeNode, targetSum: int) -> bool:
+ if not root:
+ return False
+
+ stack = [] # [(当前节点,路径数值), ...]
+ stack.append((root, 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
+```
0113.路径总和-ii
+
+**递归**
```python
# Definition for a binary tree node.
# class TreeNode:
@@ -453,35 +483,36 @@ class Solution:
# self.val = val
# self.left = left
# self.right = right
-//递归法
class Solution:
def pathSum(self, root: TreeNode, targetSum: int) -> List[List[int]]:
- path=[]
- res=[]
- def pathes(root,targetSum):
- if (not root.left) and (not root.right) and targetSum == 0: // 遇到叶子节点,并且计数为0
- res.append(path[:]) //找到一种路径,记录到res中,注意必须是path[:]而不是path
- return
- if (not root.left) and (not root.right):return // 遇到叶子节点直接返回
- if root.left: //左
- targetSum -= root.left.val
- path.append(root.left.val) //递归前记录节点
- pathes(root.left,targetSum) //递归
- targetSum += root.left.val //回溯
- path.pop() //回溯
- if root.right: //右
- targetSum -= root.right.val
- path.append(root.right.val) //递归前记录节点
- pathes(root.right,targetSum) //递归
- targetSum += root.right.val //回溯
- path.pop() //回溯
- return
-
- if root == None:return [] //处理空TreeNode
- else:
- path.append(root.val) //首先处理根节点
- pathes(root,targetSum-root.val)
- return res
+
+ def traversal(cur_node, remain):
+ if not cur_node.left and not cur_node.right and remain == 0:
+ result.append(path[:])
+ return
+
+ if not cur_node.left and not cur_node.right: return
+
+ if cur_node.left:
+ path.append(cur_node.left.val)
+ remain -= cur_node.left.val
+ traversal(cur_node.left, remain)
+ path.pop()
+ remain += cur_node.left.val
+
+ if cur_node.right:
+ path.append(cur_node.right.val)
+ remain -= cur_node.right.val
+ traversal(cur_node.right, remain)
+ path.pop()
+ remain += cur_node.right.val
+
+ result, path = [], []
+ if not root:
+ return []
+ path.append(root.val)
+ traversal(root, targetSum - root.val)
+ return result
```
Go:
From d21853a3b22763c4d1cbe02ab6a2baba349348cb Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Fri, 30 Jul 2021 11:07:38 +0800
Subject: [PATCH 030/138] =?UTF-8?q?=E6=9B=B4=E6=96=B0718.=20=E6=9C=80?=
=?UTF-8?q?=E9=95=BF=E9=87=8D=E5=A4=8D=E5=AD=90=E6=95=B0=E7=BB=84=20JavaSc?=
=?UTF-8?q?ript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0718.最长重复子数组.md | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/problems/0718.最长重复子数组.md b/problems/0718.最长重复子数组.md
index 9ee94a3d..959ed39e 100644
--- a/problems/0718.最长重复子数组.md
+++ b/problems/0718.最长重复子数组.md
@@ -252,6 +252,33 @@ func findLength(A []int, B []int) int {
}
```
+JavaScript:
+
+> 动态规划
+
+```javascript
+const findLength = (A, B) => {
+ // A、B数组的长度
+ const [m, n] = [A.length, B.length];
+ // dp数组初始化,都初始化为0
+ const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
+ // 初始化最大长度为0
+ let res = 0;
+ for (let i = 1; i <= m; i++) {
+ for (let j = 1; j <= n; j++) {
+ // 遇到A[i - 1] === B[j - 1],则更新dp数组
+ if (A[i - 1] === B[j - 1]) {
+ dp[i][j] = dp[i - 1][j - 1] + 1;
+ }
+ // 更新res
+ res = dp[i][j] > res ? dp[i][j] : res;
+ }
+ }
+ // 遍历完成,返回res
+ return res;
+};
+```
+
-----------------------
From 2119e411b73d818baaec8ca8140c7b619358bd54 Mon Sep 17 00:00:00 2001
From: xsduan98
Date: Fri, 30 Jul 2021 18:21:18 +0800
Subject: [PATCH 031/138] =?UTF-8?q?657.=20=E6=9C=BA=E5=99=A8=E4=BA=BA?=
=?UTF-8?q?=E8=83=BD=E5=90=A6=E8=BF=94=E5=9B=9E=E5=8E=9F=E7=82=B9=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0657.机器人能否返回原点.md | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/problems/0657.机器人能否返回原点.md b/problems/0657.机器人能否返回原点.md
index cd26836c..b1fb6f21 100644
--- a/problems/0657.机器人能否返回原点.md
+++ b/problems/0657.机器人能否返回原点.md
@@ -71,6 +71,21 @@ public:
## Java
```java
+// 时间复杂度:O(n)
+// 空间复杂度:如果采用 toCharArray,则是 O(n);如果使用 charAt,则是 O(1)
+class Solution {
+ public boolean judgeCircle(String moves) {
+ int x = 0;
+ int y = 0;
+ for (char c : moves.toCharArray()) {
+ if (c == 'U') y++;
+ if (c == 'D') y--;
+ if (c == 'L') x++;
+ if (c == 'R') x--;
+ }
+ return x == 0 && y == 0;
+ }
+}
```
## Python
From 58ed197ba94f17646969ddf0e45ed851f5b03961 Mon Sep 17 00:00:00 2001
From: xsduan98
Date: Fri, 30 Jul 2021 18:54:43 +0800
Subject: [PATCH 032/138] =?UTF-8?q?1365.=E6=9C=89=E5=A4=9A=E5=B0=91?=
=?UTF-8?q?=E5=B0=8F=E4=BA=8E=E5=BD=93=E5=89=8D=E6=95=B0=E5=AD=97=E7=9A=84?=
=?UTF-8?q?=E6=95=B0=E5=AD=97=20=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/1356.根据数字二进制下1的数目排序.md | 48 ++++++++++++++++++--
1 file changed, 45 insertions(+), 3 deletions(-)
diff --git a/problems/1356.根据数字二进制下1的数目排序.md b/problems/1356.根据数字二进制下1的数目排序.md
index e464f716..a3d724fa 100644
--- a/problems/1356.根据数字二进制下1的数目排序.md
+++ b/problems/1356.根据数字二进制下1的数目排序.md
@@ -16,7 +16,7 @@
换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j != i 且 nums[j] < nums[i] 。
以数组形式返回答案。
-
+
示例 1:
输入:nums = [8,1,2,2,3]
@@ -35,7 +35,7 @@
示例 3:
输入:nums = [7,7,7,7]
输出:[0,0,0,0]
-
+
提示:
* 2 <= nums.length <= 500
* 0 <= nums[i] <= 100
@@ -120,8 +120,51 @@ public:
## Java
```java
+/**
+* 解法一:暴力
+* 时间复杂度:O(n^2)
+* 空间复杂度:O(n)
+*/
+class Solution {
+ public int[] smallerNumbersThanCurrent(int[] nums) {
+ int[] res = new int[nums.length];
+ for (int i = 0; i < nums.length; i++) {
+ for (int j = 0; j < nums.length; j++) {
+ if (nums[j] < nums[i] && j != i) { // 注意 j 不能和 i 重合
+ res[i]++;
+ }
+ }
+ }
+ return res;
+ }
+}
```
+```java
+/**
+* 优化:排序 + 哈希表
+* 时间复杂度:O(nlogn)
+* 空间复杂度:O(n)
+*/
+class Solution {
+ public int[] smallerNumbersThanCurrent(int[] nums) {
+ int[] res = Arrays.copyOf(nums, nums.length);
+ Arrays.sort(res); // 是对 res 排序,nums 中顺序还要保持
+ int[] hash = new int[101]; // 使用哈希表,记录比当前元素小的元素个数
+ for (int i = res.length - 1; i >= 0; i--) { // 注意:从后向前
+ hash[res[i]] = i; // 排序后,当前下标即表示比当前元素小的元素个数
+ }
+ // 此时 hash中保存的每一个元素数值 便是 小于这个数值的个数
+ for (int i = 0; i < res.length; i++) {
+ res[i] = hash[nums[i]];
+ }
+ return res;
+ }
+}
+```
+
+
+
## Python
```python
@@ -143,4 +186,3 @@ public:
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
-
From 220ceea1edd9f5e4299eb5e6814febecb9a60573 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Fri, 30 Jul 2021 15:14:16 -0400
Subject: [PATCH 033/138] =?UTF-8?q?Update=200106.=E4=BB=8E=E4=B8=AD?=
=?UTF-8?q?=E5=BA=8F=E4=B8=8E=E5=90=8E=E5=BA=8F=E9=81=8D=E5=8E=86=E5=BA=8F?=
=?UTF-8?q?=E5=88=97=E6=9E=84=E9=80=A0=E4=BA=8C=E5=8F=89=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
上一版本隐藏了些细节.
代码格式不遵循PEP8
新版本代码改进格式并且加上注释. 同时每一步都是按照题解写出, 虽然比起上版本方法略显冗长, 但是更加利于理解. 方便初学者学习.
---
.../0106.从中序与后序遍历序列构造二叉树.md | 77 ++++++++++++-------
1 file changed, 51 insertions(+), 26 deletions(-)
diff --git a/problems/0106.从中序与后序遍历序列构造二叉树.md b/problems/0106.从中序与后序遍历序列构造二叉树.md
index 4c5a70a0..4bdc228d 100644
--- a/problems/0106.从中序与后序遍历序列构造二叉树.md
+++ b/problems/0106.从中序与后序遍历序列构造二叉树.md
@@ -654,43 +654,68 @@ class Solution {
```
Python:
+
105.从前序与中序遍历序列构造二叉树
```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 buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
- if not preorder: return None //特殊情况
- root = TreeNode(preorder[0]) //新建父节点
- p=inorder.index(preorder[0]) //找到父节点在中序遍历的位置(因为没有重复的元素,才可以这样找)
- root.left = self.buildTree(preorder[1:p+1],inorder[:p]) //注意左节点时分割中序数组和前续数组的开闭环
- root.right = self.buildTree(preorder[p+1:],inorder[p+1:]) //分割中序数组和前续数组
- return root
+ # 第一步: 特殊情况讨论: 树为空. 或者说是递归终止条件
+ if not preorder:
+ return None
+
+ # 第二步: 前序遍历的第一个就是当前的中间节点.
+ root_val = preorder[0]
+ root = TreeNode(root_val)
+
+ # 第三步: 找切割点.
+ separator_idx = inorder.index(root_val)
+
+ # 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
+ inorder_left = inorder[:separator_idx]
+ inorder_right = inorder[separator_idx + 1:]
+
+ # 第五步: 切割preorder数组. 得到preorder数组的左,右半边.
+ # ⭐️ 重点1: 中序数组大小一定跟前序数组大小是相同的.
+ preorder_left = preorder[1:1 + len(inorder_left)]
+ preorder_right = preorder[1 + len(inorder_left):]
+
+ # 第六步: 递归
+ root.left = self.buildTree(preorder_left, inorder_left)
+ root.right = self.buildTree(preorder_right, inorder_right)
+
+ return root
```
106.从中序与后序遍历序列构造二叉树
```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 buildTree(self, inorder: List[int], postorder: List[int]) -> TreeNode:
- if not postorder: return None //特殊情况
- root = TreeNode(postorder[-1]) //新建父节点
- p=inorder.index(postorder[-1]) //找到父节点在中序遍历的位置*因为没有重复的元素,才可以这样找
- root.left = self.buildTree(inorder[:p],postorder[:p]) //分割中序数组和后续数组
- root.right = self.buildTree(inorder[p+1:],postorder[p:-1]) //注意右节点时分割中序数组和后续数组的开闭环
- return root
+ # 第一步: 特殊情况讨论: 树为空. (递归终止条件)
+ if not postorder:
+ return None
+
+ # 第二步: 后序遍历的最后一个就是当前的中间节点.
+ root_val = postorder[-1]
+ root = TreeNode(root_val)
+
+ # 第三步: 找切割点.
+ separator_idx = inorder.index(root_val)
+
+ # 第四步: 切割inorder数组. 得到inorder数组的左,右半边.
+ inorder_left = inorder[:separator_idx]
+ inorder_right = inorder[separator_idx + 1:]
+
+ # 第五步: 切割postorder数组. 得到postorder数组的左,右半边.
+ # ⭐️ 重点1: 中序数组大小一定跟后序数组大小是相同的.
+ postorder_left = postorder[:len(inorder_left)]
+ postorder_right = postorder[len(inorder_left): len(postorder) - 1]
+
+ # 第六步: 递归
+ root.left = self.buildTree(inorder_left, postorder_left)
+ root.right = self.buildTree(inorder_right, postorder_right)
+
+ return root
```
Go:
> 106 从中序与后序遍历序列构造二叉树
From 4764d993b26a3a912646f810095c49142d497be8 Mon Sep 17 00:00:00 2001
From: posper
Date: Sat, 31 Jul 2021 10:20:56 +0800
Subject: [PATCH 034/138] =?UTF-8?q?657.=E6=9C=BA=E5=99=A8=E4=BA=BA?=
=?UTF-8?q?=E8=83=BD=E5=90=A6=E8=BF=94=E5=9B=9E=E5=8E=9F=E7=82=B9=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0python3=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0657.机器人能否返回原点.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/problems/0657.机器人能否返回原点.md b/problems/0657.机器人能否返回原点.md
index b1fb6f21..ba682a33 100644
--- a/problems/0657.机器人能否返回原点.md
+++ b/problems/0657.机器人能否返回原点.md
@@ -91,6 +91,20 @@ class Solution {
## Python
```python
+class Solution:
+ def judgeCircle(self, moves: str) -> bool:
+ x = 0 # 记录当前位置
+ y = 0
+ for i in range(len(moves)):
+ if (moves[i] == 'U'):
+ y += 1
+ if (moves[i] == 'D'):
+ y -= 1
+ if (moves[i] == 'L'):
+ x += 1
+ if (moves[i] == 'R'):
+ x -= 1
+ return x == 0 and y == 0
```
## Go
From 0e832d518357bb239d84e294e08a3ccecec669ea Mon Sep 17 00:00:00 2001
From: posper
Date: Sat, 31 Jul 2021 10:28:14 +0800
Subject: [PATCH 035/138] =?UTF-8?q?657.=E6=9C=BA=E5=99=A8=E4=BA=BA?=
=?UTF-8?q?=E8=83=BD=E5=90=A6=E8=BF=94=E5=9B=9E=E5=8E=9F=E7=82=B9=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0JavaScript=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0657.机器人能否返回原点.md | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/problems/0657.机器人能否返回原点.md b/problems/0657.机器人能否返回原点.md
index ba682a33..805a81e6 100644
--- a/problems/0657.机器人能否返回原点.md
+++ b/problems/0657.机器人能否返回原点.md
@@ -91,6 +91,8 @@ class Solution {
## Python
```python
+# 时间复杂度:O(n)
+# 空间复杂度:O(1)
class Solution:
def judgeCircle(self, moves: str) -> bool:
x = 0 # 记录当前位置
@@ -115,6 +117,19 @@ class Solution:
## JavaScript
```js
+// 时间复杂度:O(n)
+// 空间复杂度:O(1)
+var judgeCircle = function(moves) {
+ var x = 0; // 记录当前位置
+ var y = 0;
+ for (var i = 0; i < moves.length; i++) {
+ if (moves[i] == 'U') y++;
+ if (moves[i] == 'D') y--;
+ if (moves[i] == 'L') x++;
+ if (moves[i] == 'R') x--;
+ }
+ return x == 0 && y == 0;
+};
```
-----------------------
From 4851af73ab4ed58b71c1c6d1223c39d2483816ee Mon Sep 17 00:00:00 2001
From: posper
Date: Sat, 31 Jul 2021 10:36:59 +0800
Subject: [PATCH 036/138] =?UTF-8?q?657.=E6=9C=BA=E5=99=A8=E4=BA=BA?=
=?UTF-8?q?=E8=83=BD=E5=90=A6=E8=BF=94=E5=9B=9E=E5=8E=9F=E7=82=B9=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0go=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0657.机器人能否返回原点.md | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/problems/0657.机器人能否返回原点.md b/problems/0657.机器人能否返回原点.md
index 805a81e6..9b43ea6c 100644
--- a/problems/0657.机器人能否返回原点.md
+++ b/problems/0657.机器人能否返回原点.md
@@ -112,6 +112,25 @@ class Solution:
## Go
```go
+func judgeCircle(moves string) bool {
+ x := 0
+ y := 0
+ for i := 0; i < len(moves); i++ {
+ if moves[i] == 'U' {
+ y++
+ }
+ if moves[i] == 'D' {
+ y--
+ }
+ if moves[i] == 'L' {
+ x++
+ }
+ if moves[i] == 'R' {
+ x--
+ }
+ }
+ return x == 0 && y == 0;
+}
```
## JavaScript
From 4f5ebdabca741e124269cb5d139eaf816b5e8f4a Mon Sep 17 00:00:00 2001
From: reoooh
Date: Sun, 1 Aug 2021 00:01:37 +0800
Subject: [PATCH 037/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A00206=E7=BF=BB?=
=?UTF-8?q?=E8=BD=AC=E9=93=BE=E8=A1=A8=20Ruby=20=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0206.翻转链表.md | 43 +++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
diff --git a/problems/0206.翻转链表.md b/problems/0206.翻转链表.md
index 963d7916..4efdda3b 100644
--- a/problems/0206.翻转链表.md
+++ b/problems/0206.翻转链表.md
@@ -275,7 +275,50 @@ var reverseList = function(head) {
};
```
+Ruby:
+```ruby
+# 双指针
+# Definition for singly-linked list.
+# class ListNode
+# attr_accessor :val, :next
+# def initialize(val = 0, _next = nil)
+# @val = val
+# @next = _next
+# end
+# end
+def reverse_list(head)
+ # return nil if head.nil? # 循环判断条件亦能起到相同作用因此不必单独判断
+ cur, per = head, nil
+ until cur.nil?
+ tem = cur.next
+ cur.next = per
+ per = cur
+ cur = tem
+ end
+ per
+end
+
+# 递归
+# Definition for singly-linked list.
+# class ListNode
+# attr_accessor :val, :next
+# def initialize(val = 0, _next = nil)
+# @val = val
+# @next = _next
+# end
+# end
+def reverse_list(head)
+ reverse(nil, head)
+end
+
+def reverse(pre, cur)
+ return pre if cur.nil?
+ tem = cur.next
+ cur.next = pre
+ reverse(cur, tem) # 通过递归实现双指针法中的更新操作
+end
+```
-----------------------
From 932d27754cb34420926a41176f6fedb860768b44 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sat, 31 Jul 2021 23:04:46 -0400
Subject: [PATCH 038/138] =?UTF-8?q?Update=200617.=E5=90=88=E5=B9=B6?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
修改逻辑与题解相同.
---
problems/0617.合并二叉树.md | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md
index 19b58bd3..c5eb7594 100644
--- a/problems/0617.合并二叉树.md
+++ b/problems/0617.合并二叉树.md
@@ -312,6 +312,8 @@ class Solution {
```
Python:
+
+**递归法 - 前序遍历**
```python
# Definition for a binary tree node.
# class TreeNode:
@@ -319,16 +321,25 @@ Python:
# self.val = val
# self.left = left
# self.right = right
-# 递归法*前序遍历
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
- if not root1: return root2 // 如果t1为空,合并之后就应该是t2
- if not root2: return root1 // 如果t2为空,合并之后就应该是t1
- root1.val = root1.val + root2.val //中
- root1.left = self.mergeTrees(root1.left , root2.left) //左
- root1.right = self.mergeTrees(root1.right , root2.right) //右
- return root1 //root1修改了结构和数值
+ # 递归终止条件:
+ # 但凡有一个节点为空, 就立刻返回另外一个. 如果另外一个也为None就直接返回None.
+ if not root1:
+ return root2
+ if not root2:
+ return root1
+ # 上面的递归终止条件保证了代码执行到这里root1, root2都非空.
+ root1.val += root2.val # 中
+ root1.left = self.mergeTrees(root1.left, root2.left) #左
+ root1.right = self.mergeTrees(root1.right, root2.right) # 右
+
+ return root1 # ⚠️ 注意: 本题我们重复使用了题目给出的节点而不是创建新节点. 节省时间, 空间.
+```
+
+**迭代法**
+```python
# 迭代法-覆盖原来的树
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
From 84a12f32de997868efcfff08d25c6a161fcc5cff Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sat, 31 Jul 2021 23:10:30 -0400
Subject: [PATCH 039/138] =?UTF-8?q?Update=200617.=E5=90=88=E5=B9=B6?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
迭代法: 逻辑没有改, 只是改变顺序使之与c++代码逻辑一致.
---
problems/0617.合并二叉树.md | 51 +++++++++++++++++++++----------------
1 file changed, 29 insertions(+), 22 deletions(-)
diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md
index c5eb7594..09d844f3 100644
--- a/problems/0617.合并二叉树.md
+++ b/problems/0617.合并二叉树.md
@@ -340,31 +340,38 @@ class Solution:
**迭代法**
```python
-# 迭代法-覆盖原来的树
class Solution:
def mergeTrees(self, root1: TreeNode, root2: TreeNode) -> TreeNode:
- if not root1: return root2
- if not root2: return root1
- # 迭代,将树2覆盖到树1
- queue1 = [root1]
- queue2 = [root2]
- root = root1
- while queue1 and queue2:
- root1 = queue1.pop(0)
- root2 = queue2.pop(0)
- root1.val += root2.val
- if not root1.left: # 如果树1左儿子不存在,则覆盖后树1的左儿子为树2的左儿子
- root1.left = root2.left
- elif root1.left and root2.left:
- queue1.append(root1.left)
- queue2.append(root2.left)
+ if not root1:
+ return root2
+ if not root2:
+ return root1
- if not root1.right: # 同理,处理右儿子
- root1.right = root2.right
- elif root1.right and root2.right:
- queue1.append(root1.right)
- queue2.append(root2.right)
- return root
+ queue = deque()
+ queue.append(root1)
+ queue.append(root2)
+
+ while queue:
+ node1 = queue.popleft()
+ node2 = queue.popleft()
+ # 更新queue
+ # 只有两个节点都有左节点时, 再往queue里面放.
+ if node1.left and node2.left:
+ queue.append(node1.left)
+ queue.append(node2.left)
+ # 只有两个节点都有右节点时, 再往queue里面放.
+ if node1.right and node2.right:
+ queue.append(node1.right)
+ queue.append(node2.right)
+
+ # 更新当前节点. 同时改变当前节点的左右孩子.
+ node1.val += node2.val
+ if not node1.left and node2.left:
+ node1.left = node2.left
+ if not node1.right and node2.right:
+ node1.right = node2.right
+
+ return root1
```
Go:
From 5d1c0883079d6e791804e086e928882a7c091831 Mon Sep 17 00:00:00 2001
From: posper
Date: Sun, 1 Aug 2021 11:16:22 +0800
Subject: [PATCH 040/138] =?UTF-8?q?232.=E7=94=A8=E6=A0=88=E5=AE=9E?=
=?UTF-8?q?=E7=8E=B0=E9=98=9F=E5=88=97=EF=BC=8C=E4=B9=8B=E5=89=8D=E7=9A=84?=
=?UTF-8?q?js=E4=BB=A3=E7=A0=81=E6=94=BE=E5=88=B0=E4=BA=86go=E7=9A=84?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=9D=97=E4=B8=AD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0232.用栈实现队列.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/problems/0232.用栈实现队列.md b/problems/0232.用栈实现队列.md
index 6890fc2b..32476d6f 100644
--- a/problems/0232.用栈实现队列.md
+++ b/problems/0232.用栈实现队列.md
@@ -384,7 +384,7 @@ func (this *MyQueue) Peek() int {
func (this *MyQueue) Empty() bool {
return len(this.stack) == 0 && len(this.back) == 0
}
-
+```
javaScript:
@@ -442,8 +442,6 @@ MyQueue.prototype.empty = function() {
```
-
-
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
From 7757a60d0ebbe729443be57adccfe3716837dfc9 Mon Sep 17 00:00:00 2001
From: posper
Date: Sun, 1 Aug 2021 11:20:13 +0800
Subject: [PATCH 041/138] =?UTF-8?q?34.=E5=9C=A8=E6=8E=92=E5=BA=8F=E6=95=B0?=
=?UTF-8?q?=E7=BB=84=E4=B8=AD=E6=9F=A5=E6=89=BE=E5=85=83=E7=B4=A0=E7=9A=84?=
=?UTF-8?q?=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=92=8C=E6=9C=80=E5=90=8E=E4=B8=80?=
=?UTF-8?q?=E4=B8=AA=E4=BD=8D=E7=BD=AE=EF=BC=8CJava=E7=89=88=E6=9C=AC?=
=?UTF-8?q?=E8=A7=A3=E6=B3=952=E6=B3=A8=E9=87=8A=E4=BF=AE=E6=94=B9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0034.在排序数组中查找元素的第一个和最后一个位置.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
index 97b9a9b6..f6b01dae 100644
--- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
+++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
@@ -223,7 +223,7 @@ class Solution {
// 解法2
// 1、首先,在 nums 数组中二分查找 target;
// 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
-// 3、如果二分查找失败,则 binarySearch 返回 nums 中 为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
+// 3、如果二分查找成功,则 binarySearch 返回 nums 中值为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
class Solution {
public int[] searchRange(int[] nums, int target) {
From 173618289d531b74e1a7e04972d88dcb790a9ac0 Mon Sep 17 00:00:00 2001
From: YellowPeaches <326826436@qq.com>
Date: Sun, 1 Aug 2021 13:44:57 +0800
Subject: [PATCH 042/138] =?UTF-8?q?=E6=9B=B4=E6=96=B0143.=E9=87=8D?=
=?UTF-8?q?=E6=8E=92=E9=93=BE=E8=A1=A8=20=E5=A2=9E=E5=8A=A0Java=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0143.重排链表.md | 49 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/problems/0143.重排链表.md b/problems/0143.重排链表.md
index c4e8d8f7..dc0095d3 100644
--- a/problems/0143.重排链表.md
+++ b/problems/0143.重排链表.md
@@ -1,4 +1,3 @@
-
@@ -63,6 +62,7 @@ public:
## 方法二
把链表放进双向队列,然后通过双向队列一前一后弹出数据,来构造新的链表。这种方法比操作数组容易一些,不用双指针模拟一前一后了
+
```C++
class Solution {
public:
@@ -176,6 +176,51 @@ public:
Java:
+```java
+public class ReorderList {
+ public void reorderList(ListNode head) {
+ ListNode fast = head, slow = head;
+ //求出中点
+ while (fast.next != null && fast.next.next != null) {
+ slow = slow.next;
+ fast = fast.next.next;
+ }
+ //right就是右半部分 12345 就是45 1234 就是34
+ ListNode right = slow.next;
+ //断开左部分和右部分
+ slow.next = null;
+ //反转右部分 right就是反转后右部分的起点
+ right = reverseList(right);
+ //左部分的起点
+ ListNode left = head;
+ //进行左右部分来回连接
+ //这里左部分的节点个数一定大于等于右部分的节点个数 因此只判断right即可
+ while (right != null) {
+ ListNode curLeft = left.next;
+ left.next = right;
+ left = curLeft;
+
+ ListNode curRight = right.next;
+ right.next = left;
+ right = curRight;
+ }
+ }
+
+ public ListNode reverseList(ListNode head) {
+ ListNode headNode = new ListNode(0);
+ ListNode cur = head;
+ ListNode next = null;
+ while (cur != null) {
+ next = cur.next;
+ cur.next = headNode.next;
+ headNode.next = cur;
+ cur = next;
+ }
+ return headNode.next;
+ }
+}
+```
+
Python:
Go:
@@ -183,8 +228,10 @@ Go:
JavaScript:
-----------------------
+
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
* 知识星球:[代码随想录](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)
+
From a8109b40141202dd9782f5389f0816c8057999c5 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sun, 1 Aug 2021 10:15:22 -0400
Subject: [PATCH 043/138] =?UTF-8?q?Update=200700.=E4=BA=8C=E5=8F=89?=
=?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E6=90=9C=E7=B4=A2?=
=?UTF-8?q?.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
更改代码符合PEP 8 规范.
---
problems/0700.二叉搜索树中的搜索.md | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/problems/0700.二叉搜索树中的搜索.md b/problems/0700.二叉搜索树中的搜索.md
index d6899ac5..e6eb0358 100644
--- a/problems/0700.二叉搜索树中的搜索.md
+++ b/problems/0700.二叉搜索树中的搜索.md
@@ -212,17 +212,20 @@ 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:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
- if not root or root.val == val: return root //为空或者已经找到都是直接返回root,所以合并了
- if root.val > val: return self.searchBST(root.left,val) //注意一定要加return
- else: return self.searchBST(root.right,val)
+ # 为什么要有返回值:
+ # 因为搜索到目标节点就要立即return,
+ # 这样才是找到节点就返回(搜索某一条边),如果不加return,就是遍历整棵树了。
+
+ if not root or root.val == val:
+ return root
+
+ if root.val > val:
+ return self.searchBST(root.left, val)
+
+ if root.val < val:
+ return self.searchBST(root.right, val)
```
From 2a94d6ca0f413d461537f112cfb8b99855b13cd5 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sun, 1 Aug 2021 10:17:03 -0400
Subject: [PATCH 044/138] =?UTF-8?q?Update=200700.=E4=BA=8C=E5=8F=89?=
=?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E6=90=9C=E7=B4=A2?=
=?UTF-8?q?.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0700.二叉搜索树中的搜索.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/problems/0700.二叉搜索树中的搜索.md b/problems/0700.二叉搜索树中的搜索.md
index e6eb0358..4b02f8af 100644
--- a/problems/0700.二叉搜索树中的搜索.md
+++ b/problems/0700.二叉搜索树中的搜索.md
@@ -212,6 +212,12 @@ 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:
def searchBST(self, root: TreeNode, val: int) -> TreeNode:
# 为什么要有返回值:
From 3ef151383e3e6aec9b4c6ae14e9dcfa2138f0b8b Mon Sep 17 00:00:00 2001
From: fixme
Date: Sun, 1 Aug 2021 23:06:26 +0800
Subject: [PATCH 045/138] =?UTF-8?q?=E3=80=90707=5F=E8=AE=BE=E8=AE=A1?=
=?UTF-8?q?=E9=93=BE=E8=A1=A8=E3=80=91=E5=A2=9E=E5=8A=A0C=E5=AE=9E?=
=?UTF-8?q?=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0707.设计链表.md | 122 ++++++++++++++++++++++++++++++++++++++
1 file changed, 122 insertions(+)
diff --git a/problems/0707.设计链表.md b/problems/0707.设计链表.md
index 8be28f88..349e2409 100644
--- a/problems/0707.设计链表.md
+++ b/problems/0707.设计链表.md
@@ -154,7 +154,129 @@ private:
## 其他语言版本
+C:
+```C
+typedef struct {
+ int val;
+ struct MyLinkedList* next;
+}MyLinkedList;
+/** Initialize your data structure here. */
+
+MyLinkedList* myLinkedListCreate() {
+ //这个题必须用虚拟头指针,参数都是一级指针,头节点确定后没法改指向了!!!
+ MyLinkedList* head = (MyLinkedList *)malloc(sizeof (MyLinkedList));
+ head->next = NULL;
+ return head;
+}
+
+/** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */
+int myLinkedListGet(MyLinkedList* obj, int index) {
+ MyLinkedList *cur = obj->next;
+ for (int i = 0; cur != NULL; i++){
+ if (i == index){
+ return cur->val;
+ }
+ else{
+ cur = cur->next;
+ }
+ }
+ return -1;
+}
+
+/** 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. */
+void myLinkedListAddAtHead(MyLinkedList* obj, int val) {
+ MyLinkedList *nhead = (MyLinkedList *)malloc(sizeof (MyLinkedList));
+ nhead->val = val;
+ nhead->next = obj->next;
+ obj->next = nhead;
+
+}
+
+/** Append a node of value val to the last element of the linked list. */
+void myLinkedListAddAtTail(MyLinkedList* obj, int val) {
+ MyLinkedList *cur = obj;
+ while(cur->next != NULL){
+ cur = cur->next;
+ }
+ MyLinkedList *ntail = (MyLinkedList *)malloc(sizeof (MyLinkedList));
+ ntail->val = val;
+ ntail->next = NULL;
+ cur->next = ntail;
+}
+
+/** 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. */
+void myLinkedListAddAtIndex(MyLinkedList* obj, int index, int val) {
+ if (index == 0){
+ myLinkedListAddAtHead(obj, val);
+ return;
+ }
+ MyLinkedList *cur = obj->next;
+ for (int i = 1 ;cur != NULL; i++){
+ if (i == index){
+ MyLinkedList* newnode = (MyLinkedList *)malloc(sizeof (MyLinkedList));
+ newnode->val = val;
+ newnode->next = cur->next;
+ cur->next = newnode;
+ return;
+ }
+ else{
+ cur = cur->next;
+ }
+ }
+}
+
+/** Delete the index-th node in the linked list, if the index is valid. */
+void myLinkedListDeleteAtIndex(MyLinkedList* obj, int index) {
+ if (index == 0){
+ MyLinkedList *tmp = obj->next;
+ if (tmp != NULL){
+ obj->next = tmp->next;
+ free(tmp)
+ }
+ return;
+ }
+ MyLinkedList *cur = obj->next;
+ for (int i = 1 ;cur != NULL && cur->next != NULL; i++){
+ if (i == index){
+ MyLinkedList *tmp = cur->next;
+ if (tmp != NULL) {
+ cur->next = tmp->next;
+ free(tmp);
+ }
+ return;
+ }
+ else{
+ cur = cur->next;
+ }
+ }
+
+}
+
+void myLinkedListFree(MyLinkedList* obj) {
+ while(obj != NULL){
+ MyLinkedList *tmp = obj;
+ obj = obj->next;
+ free(tmp);
+ }
+}
+
+/**
+ * Your MyLinkedList struct will be instantiated and called as such:
+ * MyLinkedList* obj = myLinkedListCreate();
+ * int param_1 = myLinkedListGet(obj, index);
+
+ * myLinkedListAddAtHead(obj, val);
+
+ * myLinkedListAddAtTail(obj, val);
+
+ * myLinkedListAddAtIndex(obj, index, val);
+
+ * myLinkedListDeleteAtIndex(obj, index);
+
+ * myLinkedListFree(obj);
+*/
+```
Java:
```Java
From b87d619cdd1ab886055d94cb4b878f550fe51ea7 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sun, 1 Aug 2021 13:54:51 -0400
Subject: [PATCH 046/138] =?UTF-8?q?Update=200098.=E9=AA=8C=E8=AF=81?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
更改递归部分代码
1. 更新上一版代码格式 使其更符合PEP8.
2. 把代码细节都暴露出来, 逻辑更加清晰.
---
problems/0098.验证二叉搜索树.md | 34 +++++++++++++++++++++++----------
1 file changed, 24 insertions(+), 10 deletions(-)
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index 248d10f1..a271b977 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -337,6 +337,8 @@ class Solution {
```
Python:
+
+**递归** - 利用BST中序遍历特性
```python
# Definition for a binary tree node.
# class TreeNode:
@@ -344,18 +346,30 @@ Python:
# self.val = val
# self.left = left
# self.right = right
-# 递归法
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
- res = [] //把二叉搜索树按中序遍历写成list
- def buildalist(root):
- if not root: return
- buildalist(root.left) //左
- res.append(root.val) //中
- buildalist(root.right) //右
- return res
- buildalist(root)
- return res == sorted(res) and len(set(res)) == len(res) //检查list里的数有没有重复元素,以及是否按从小到大排列
+ # 思路: 利用BST中序遍历的特性.
+ # 中序遍历输出的二叉搜索树节点的数值是有序序列
+ candidate_list = []
+
+ def __traverse(root: TreeNode) -> None:
+ nonlocal candidate_list
+ if not root:
+ return
+ __traverse(root.left)
+ candidate_list.append(root.val)
+ __traverse(root.right)
+
+ def __is_sorted(nums: list) -> bool:
+ for i in range(1, len(nums)):
+ if nums[i] <= nums[i - 1]:
+ return False
+ return True
+
+ __traverse(root)
+ res = __is_sorted(candidate_list)
+
+ return res
# 简单递归法
class Solution:
From 6178dff832cebd336c596ae40ae941ab28cd42c2 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sun, 1 Aug 2021 13:57:12 -0400
Subject: [PATCH 047/138] =?UTF-8?q?Update=200098.=E9=AA=8C=E8=AF=81?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加comment
---
problems/0098.验证二叉搜索树.md | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index a271b977..cf8651f3 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -338,7 +338,7 @@ class Solution {
Python:
-**递归** - 利用BST中序遍历特性
+**递归** - 利用BST中序遍历特性,把树"压缩"成数组
```python
# Definition for a binary tree node.
# class TreeNode:
@@ -362,7 +362,7 @@ class Solution:
def __is_sorted(nums: list) -> bool:
for i in range(1, len(nums)):
- if nums[i] <= nums[i - 1]:
+ if nums[i] <= nums[i - 1]: # ⚠️ 注意: Leetcode定义二叉搜索树中不能有重复元素
return False
return True
@@ -370,8 +370,11 @@ class Solution:
res = __is_sorted(candidate_list)
return res
+```
-# 简单递归法
+**递归** -
+
+```python
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
def isBST(root, min_val, max_val):
From 59fdafc7a116ca694b19ba78721bdc416cda76e8 Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Mon, 2 Aug 2021 08:58:19 +0800
Subject: [PATCH 048/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A053.=E6=9C=80=E5=A4=A7?=
=?UTF-8?q?=E5=AD=90=E5=BA=8F=E5=92=8C(=E5=8A=A8=E6=80=81=E8=A7=84?=
=?UTF-8?q?=E5=88=92)-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0053.最大子序和(动态规划).md | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/problems/0053.最大子序和(动态规划).md b/problems/0053.最大子序和(动态规划).md
index ada378b2..20a8c66c 100644
--- a/problems/0053.最大子序和(动态规划).md
+++ b/problems/0053.最大子序和(动态规划).md
@@ -168,6 +168,23 @@ func max(a,b int) int{
}
```
+JavaScript:
+
+```javascript
+const maxSubArray = nums => {
+ // 数组长度,dp初始化
+ const [len, dp] = [nums.length, [nums[0]]];
+ // 最大值初始化为dp[0]
+ let max = dp[0];
+ for (let i = 1; i < len; i++) {
+ dp[i] = Math.max(dp[i - 1] + nums[i], nums[i]);
+ // 更新最大值
+ max = Math.max(max, dp[i]);
+ }
+ return max;
+};
+```
+
-----------------------
From 9a87b13fc3f87c1b46310d1c8da92b7b8ca8d078 Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Mon, 2 Aug 2021 09:16:10 +0800
Subject: [PATCH 049/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0392.=E5=88=A4?=
=?UTF-8?q?=E6=96=AD=E5=AD=90=E5=BA=8F=E5=88=97(=E5=8A=A8=E6=80=81?=
=?UTF-8?q?=E8=A7=84=E5=88=92)-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0392.判断子序列.md | 25 ++++++++++++++++++++++++-
1 file changed, 24 insertions(+), 1 deletion(-)
diff --git a/problems/0392.判断子序列.md b/problems/0392.判断子序列.md
index d97d2684..09ee2c4d 100644
--- a/problems/0392.判断子序列.md
+++ b/problems/0392.判断子序列.md
@@ -180,7 +180,30 @@ class Solution:
return False
```
-Go:
+JavaScript:
+
+```javascript
+const isSubsequence = (s, t) => {
+ // s、t的长度
+ const [m, n] = [s.length, t.length];
+ // dp全初始化为0
+ const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
+ for (let i = 1; i <= m; i++) {
+ for (let j = 1; j <= n; j++) {
+ // 更新dp[i][j],两种情况
+ if (s[i - 1] === t[j - 1]) {
+ dp[i][j] = dp[i - 1][j - 1] + 1;
+ } else {
+ dp[i][j] = dp[i][j - 1];
+ }
+ }
+ }
+ // 遍历结束,判断dp右下角的数是否等于s的长度
+ return dp[m][n] === m ? true : false;
+};
+```
+
+
From 0fdede8c944b5052160370b3fe1241810021cfa3 Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Sun, 1 Aug 2021 22:53:23 -0400
Subject: [PATCH 050/138] =?UTF-8?q?Update=200098.=E9=AA=8C=E8=AF=81?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
将上一版本的代码改成跟题解思路相同.
---
problems/0098.验证二叉搜索树.md | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/problems/0098.验证二叉搜索树.md b/problems/0098.验证二叉搜索树.md
index cf8651f3..a7634849 100644
--- a/problems/0098.验证二叉搜索树.md
+++ b/problems/0098.验证二叉搜索树.md
@@ -372,18 +372,30 @@ class Solution:
return res
```
-**递归** -
+**递归** - 标准做法
```python
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
- def isBST(root, min_val, max_val):
- if not root: return True
- if root.val >= max_val or root.val <= min_val:
+ # 规律: BST的中序遍历节点数值是从小到大.
+ cur_max = -float("INF")
+ def __isValidBST(root: TreeNode) -> bool:
+ nonlocal cur_max
+
+ if not root:
+ return True
+
+ is_left_valid = __isValidBST(root.left)
+ if cur_max < root.val:
+ cur_max = root.val
+ else:
return False
- return isBST(root.left, min_val, root.val) and isBST(root.right, root.val, max_val)
- return isBST(root, float("-inf"), float("inf"))
-
+ is_right_valid = __isValidBST(root.right)
+
+ return is_left_valid and is_right_valid
+ return __isValidBST(root)
+```
+```
# 迭代-中序遍历
class Solution:
def isValidBST(self, root: TreeNode) -> bool:
From 152f7cc61a8e5891374b14c0ac998995fe3da767 Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Tue, 3 Aug 2021 08:45:05 +0800
Subject: [PATCH 051/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A01035.=E4=B8=8D?=
=?UTF-8?q?=E7=9B=B8=E4=BA=A4=E7=9A=84=E7=BA=BF-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/1035.不相交的线.md | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/problems/1035.不相交的线.md b/problems/1035.不相交的线.md
index cb74ef75..3a0e6a68 100644
--- a/problems/1035.不相交的线.md
+++ b/problems/1035.不相交的线.md
@@ -109,7 +109,28 @@ class Solution:
return dp[-1][-1]
```
-Go:
+JavaScript:
+
+```javascript
+const maxUncrossedLines = (nums1, nums2) => {
+ // 两个数组长度
+ const [m, n] = [nums1.length, nums2.length];
+ // 创建dp数组并都初始化为0
+ const dp = new Array(m + 1).fill(0).map(x => new Array(n + 1).fill(0));
+ for (let i = 1; i <= m; i++) {
+ for (let j = 1; j <= n; j++) {
+ // 根据两种情况更新dp[i][j]
+ if (nums1[i - 1] === nums2[j - 1]) {
+ dp[i][j] = dp[i - 1][j - 1] + 1;
+ } else {
+ dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
+ }
+ }
+ }
+ // 返回dp数组中右下角的元素
+ return dp[m][n];
+};
+```
From 7cc60a02a7c62df1784ad9deca39cc7822f0e6e7 Mon Sep 17 00:00:00 2001
From: ltinyho
Date: Tue, 3 Aug 2021 10:34:24 +0800
Subject: [PATCH 052/138] =?UTF-8?q?1002.=E6=9F=A5=E6=89=BE=E5=B8=B8?=
=?UTF-8?q?=E7=94=A8=E5=AD=97=E7=AC=A6-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/1002.查找常用字符.md | 40 +++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/problems/1002.查找常用字符.md b/problems/1002.查找常用字符.md
index 875340c4..e3014d00 100644
--- a/problems/1002.查找常用字符.md
+++ b/problems/1002.查找常用字符.md
@@ -169,6 +169,46 @@ class Solution {
}
}
```
+javaScript
+```js
+var commonChars = function (words) {
+ let res = []
+ let size = 26
+ let firstHash = new Array(size)
+ for (let i = 0; i < size; i++) { // 初始化 hash 数组
+ firstHash[i] = 0
+ }
+
+ let a = "a".charCodeAt()
+ let firstWord = words[0]
+ for (let i = 0; i < firstWord.length; i++) { // 第 0 个单词的统计
+ let idx = firstWord[i].charCodeAt()
+ firstHash[idx - a] += 1
+ }
+
+ for (let i = 1; i < words.length; i++) { // 1-n 个单词统计
+ let otherHash = new Array(size)
+ for (let i = 0; i < size; i++) { // 初始化 hash 数组
+ otherHash[i] = 0
+ }
+
+ for (let j = 0; j < words[i].length; j++) {
+ let idx = words[i][j].charCodeAt()
+ otherHash[idx - a] += 1
+ }
+ for (let i = 0; i < size; i++) {
+ firstHash[i] = Math.min(firstHash[i], otherHash[i])
+ }
+ }
+ for (let i = 0; i < size; i++) {
+ while (firstHash[i] > 0) {
+ res.push(String.fromCharCode(i + a))
+ firstHash[i]--
+ }
+ }
+ return res
+};
+```
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
From 4068040965153cbcbdd970be6abf5fa31be517f0 Mon Sep 17 00:00:00 2001
From: ltinyho
Date: Tue, 3 Aug 2021 14:43:44 +0800
Subject: [PATCH 053/138] =?UTF-8?q?0018.=E5=9B=9B=E6=95=B0=E4=B9=8B?=
=?UTF-8?q?=E5=92=8C-golang?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0018.四数之和.md | 48 +++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/problems/0018.四数之和.md b/problems/0018.四数之和.md
index 0caf12be..4a8fa947 100644
--- a/problems/0018.四数之和.md
+++ b/problems/0018.四数之和.md
@@ -201,6 +201,54 @@ class Solution(object):
```
Go:
+```go
+func fourSum(nums []int, target int) [][]int {
+ if len(nums) < 4 {
+ return nil
+ }
+ sort.Ints(nums)
+ var res [][]int
+ for i := 0; i < len(nums)-3; i++ {
+ n1 := nums[i]
+ // if n1 > target { // 不能这样写,因为可能是负数
+ // break
+ // }
+ if i > 0 && n1 == nums[i-1] {
+ continue
+ }
+ for j := i + 1; j < len(nums)-2; j++ {
+ n2 := nums[j]
+ if j > i+1 && n2 == nums[j-1] {
+ continue
+ }
+ l := j + 1
+ r := len(nums) - 1
+ for l < r {
+ n3 := nums[l]
+ n4 := nums[r]
+ sum := n1 + n2 + n3 + n4
+ if sum < target {
+ l++
+ } else if sum > target {
+ r--
+ } else {
+ res = append(res, []int{n1, n2, n3, n4})
+ for l < r && n3 == nums[l+1] { // 去重
+ l++
+ }
+ for l < r && n4 == nums[r-1] { // 去重
+ r--
+ }
+ // 找到答案时,双指针同时靠近
+ r--
+ l++
+ }
+ }
+ }
+ }
+ return res
+}
+```
javaScript:
From 7ff7afcfaac673ba846cc5908aa68ee13d811fe0 Mon Sep 17 00:00:00 2001
From: YellowPeaches <326826436@qq.com>
Date: Tue, 3 Aug 2021 16:25:05 +0800
Subject: [PATCH 054/138] =?UTF-8?q?update=200100=E7=9B=B8=E5=90=8C?=
=?UTF-8?q?=E7=9A=84=E6=A0=91java=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0100.相同的树.md | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/problems/0100.相同的树.md b/problems/0100.相同的树.md
index b536ffe3..c40f79fd 100644
--- a/problems/0100.相同的树.md
+++ b/problems/0100.相同的树.md
@@ -172,6 +172,22 @@ public:
Java:
+```java
+class Solution {
+ public boolean isSameTree(TreeNode p, TreeNode q) {
+ if (p == null && q == null) {
+ return true;
+ } else if (q == null || p == null) {
+ return false;
+ } else if (q.val != p.val) {
+ return false;
+ } else {
+ return isSameTree(q.left, p.left) && isSameTree(q.right, p.right);
+ }
+ }
+}
+
+```
Python:
Go:
From 60799a2f446b0b54bb6dcf29ef302ecf9dfeb3e6 Mon Sep 17 00:00:00 2001
From: posper
Date: Tue, 3 Aug 2021 20:53:53 +0800
Subject: [PATCH 055/138] =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E5=B1=82?=
=?UTF-8?q?=E5=BA=8F=E9=81=8D=E5=8E=86=20116.=E5=A1=AB=E5=85=85=E6=AF=8F?=
=?UTF-8?q?=E4=B8=AA=E8=8A=82=E7=82=B9=E7=9A=84=E4=B8=8B=E4=B8=80=E4=B8=AA?=
=?UTF-8?q?=E5=8F=B3=E4=BE=A7=E8=8A=82=E7=82=B9=E6=8C=87=E9=92=88=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0Java=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0102.二叉树的层序遍历.md | 38 +++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md
index 8be3ac47..7d459ad9 100644
--- a/problems/0102.二叉树的层序遍历.md
+++ b/problems/0102.二叉树的层序遍历.md
@@ -1254,6 +1254,44 @@ func connect(root *Node) *Node {
}
```
+Java 代码:
+
+```java
+// 二叉树之层次遍历
+class Solution {
+ public Node connect(Node root) {
+ Queue queue = new LinkedList<>();
+ if (root != null) {
+ queue.add(root);
+ }
+ while (!queue.isEmpty()) {
+ int size = queue.size();
+ Node node = null;
+ Node nodePre = null;
+
+ for (int i = 0; i < size; i++) {
+ if (i == 0) {
+ nodePre = queue.poll(); // 取出本层头一个节点
+ node = nodePre;
+ } else {
+ node = queue.poll();
+ nodePre.next = node; // 本层前一个节点 next 指向当前节点
+ nodePre = nodePre.next;
+ }
+ if (node.left != null) {
+ queue.add(node.left);
+ }
+ if (node.right != null) {
+ queue.add(node.right);
+ }
+ }
+ nodePre.next = null; // 本层最后一个节点 next 指向 null
+ }
+ return root;
+ }
+}
+```
+
## 117.填充每个节点的下一个右侧节点指针II
题目地址:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/
From c62d6255013161bfba38ebf70e38cca410dba15c Mon Sep 17 00:00:00 2001
From: ironartisan
Date: Tue, 3 Aug 2021 21:58:23 +0800
Subject: [PATCH 056/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200034.=E5=9C=A8?=
=?UTF-8?q?=E6=8E=92=E5=BA=8F=E6=95=B0=E7=BB=84=E4=B8=AD=E6=9F=A5=E6=89=BE?=
=?UTF-8?q?=E5=85=83=E7=B4=A0=E7=9A=84=E7=AC=AC=E4=B8=80=E4=B8=AA=E5=92=8C?=
=?UTF-8?q?=E6=9C=80=E5=90=8E=E4=B8=80=E4=B8=AA=E4=BD=8D=E7=BD=AEpython3?=
=?UTF-8?q?=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...排序数组中查找元素的第一个和最后一个位置.md | 113 +++++++++++++++++-
1 file changed, 112 insertions(+), 1 deletion(-)
diff --git a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
index f6b01dae..ced4d4ac 100644
--- a/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
+++ b/problems/0034.在排序数组中查找元素的第一个和最后一个位置.md
@@ -50,7 +50,7 @@
接下来,在去寻找左边界,和右边界了。
-采用二分法来取寻找左右边界,为了让代码清晰,我分别写两个二分来寻找左边界和右边界。
+采用二分法来去寻找左右边界,为了让代码清晰,我分别写两个二分来寻找左边界和右边界。
**刚刚接触二分搜索的同学不建议上来就像如果用一个二分来查找左右边界,很容易把自己绕进去,建议扎扎实实的写两个二分分别找左边界和右边界**
@@ -275,6 +275,117 @@ class Solution {
## Python
```python
+class Solution:
+ def searchRange(self, nums: List[int], target: int) -> List[int]:
+ def getRightBorder(nums:List[int], target:int) -> int:
+ left, right = 0, len(nums)-1
+ rightBoder = -2 # 记录一下rightBorder没有被赋值的情况
+ while left <= right:
+ middle = left + (right-left) // 2
+ if nums[middle] > target:
+ right = middle - 1
+ else: # 寻找右边界,nums[middle] == target的时候更新left
+ left = middle + 1
+ rightBoder = left
+
+ return rightBoder
+
+ def getLeftBorder(nums:List[int], target:int) -> int:
+ left, right = 0, len(nums)-1
+ leftBoder = -2 # 记录一下leftBorder没有被赋值的情况
+ while left <= right:
+ middle = left + (right-left) // 2
+ if nums[middle] >= target: # 寻找左边界,nums[middle] == target的时候更新right
+ right = middle - 1;
+ leftBoder = right;
+ else:
+ left = middle + 1
+ return leftBoder
+ leftBoder = getLeftBorder(nums, target)
+ rightBoder = getRightBorder(nums, target)
+ # 情况一
+ if leftBoder == -2 or rightBoder == -2: return [-1, -1]
+ # 情况三
+ if rightBoder -leftBoder >1: return [leftBoder + 1, rightBoder - 1]
+ # 情况二
+ return [-1, -1]
+```
+```python
+# 解法2
+# 1、首先,在 nums 数组中二分查找 target;
+# 2、如果二分查找失败,则 binarySearch 返回 -1,表明 nums 中没有 target。此时,searchRange 直接返回 {-1, -1};
+# 3、如果二分查找成功,则 binarySearch 返回 nums 中值为 target 的一个下标。然后,通过左右滑动指针,来找到符合题意的区间
+class Solution:
+ def searchRange(self, nums: List[int], target: int) -> List[int]:
+ def binarySearch(nums:List[int], target:int) -> int:
+ left, right = 0, len(nums)-1
+ while left<=right: # 不变量:左闭右闭区间
+ middle = left + (right-left) // 2
+ if nums[middle] > target:
+ right = middle - 1
+ elif nums[middle] < target:
+ left = middle + 1
+ else:
+ return middle
+ return -1
+ index = binarySearch(nums, target)
+ if index == -1:return [-1, -1] # nums 中不存在 target,直接返回 {-1, -1}
+ # nums 中存在 targe,则左右滑动指针,来找到符合题意的区间
+ left, right = index, index
+ # 向左滑动,找左边界
+ while left -1 >=0 and nums[left - 1] == target: left -=1
+ # 向右滑动,找右边界
+ while right+1 < len(nums) and nums[right + 1] == target: right +=1
+ return [left, right]
+```
+```python
+# 解法3
+# 1、首先,在 nums 数组中二分查找得到第一个大于等于 target的下标(左边界)与第一个大于target的下标(右边界);
+# 2、如果左边界<= 右边界,则返回 [左边界, 右边界]。否则返回[-1, -1]
+class Solution:
+ def searchRange(self, nums: List[int], target: int) -> List[int]:
+ def binarySearch(nums:List[int], target:int, lower:bool) -> int:
+ left, right = 0, len(nums)-1
+ ans = len(nums)
+ while left<=right: # 不变量:左闭右闭区间
+ middle = left + (right-left) //2
+ # lower为True,执行前半部分,找到第一个大于等于 target的下标 ,否则找到第一个大于target的下标
+ if nums[middle] > target or (lower and nums[middle] >= target):
+ right = middle - 1
+ ans = middle
+ else:
+ left = middle + 1
+ return ans
+
+ leftBorder = binarySearch(nums, target, True) # 搜索左边界
+ rightBorder = binarySearch(nums, target, False) -1 # 搜索右边界
+ if leftBorder<= rightBorder and rightBorder< len(nums) and nums[leftBorder] == target and nums[rightBorder] == target:
+ return [leftBorder, rightBorder]
+ return [-1, -1]
+```
+
+```python
+# 解法4
+# 1、首先,在 nums 数组中二分查找得到第一个大于等于 target的下标leftBorder;
+# 2、在 nums 数组中二分查找得到第一个大于等于 target+1的下标, 减1则得到rightBorder;
+# 3、如果开始位置在数组的右边或者不存在target,则返回[-1, -1] 。否则返回[leftBorder, rightBorder]
+class Solution:
+ def searchRange(self, nums: List[int], target: int) -> List[int]:
+ def binarySearch(nums:List[int], target:int) -> int:
+ left, right = 0, len(nums)-1
+ while left<=right: # 不变量:左闭右闭区间
+ middle = left + (right-left) //2
+ if nums[middle] >= target:
+ right = middle - 1
+ else:
+ left = middle + 1
+ return left # 若存在target,则返回第一个等于target的值
+
+ leftBorder = binarySearch(nums, target) # 搜索左边界
+ rightBorder = binarySearch(nums, target+1) -1 # 搜索右边界
+ if leftBorder == len(nums) or nums[leftBorder]!= target: # 情况一和情况二
+ return [-1, -1]
+ return [leftBorder, rightBorder]
```
## Go
From 26a07b9bf1597ceda73c4a616aea29395f2c0341 Mon Sep 17 00:00:00 2001
From: fixme
Date: Tue, 3 Aug 2021 22:10:15 +0800
Subject: [PATCH 057/138] =?UTF-8?q?=E3=80=9024.=20=E4=B8=A4=E4=B8=A4?=
=?UTF-8?q?=E4=BA=A4=E6=8D=A2=E9=93=BE=E8=A1=A8=E4=B8=AD=E7=9A=84=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E3=80=91C=E5=AE=9E=E7=8E=B0(=E5=8F=8C=E6=8C=87?=
=?UTF-8?q?=E9=92=88)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0024.两两交换链表中的节点.md | 28 +++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/problems/0024.两两交换链表中的节点.md b/problems/0024.两两交换链表中的节点.md
index 66e149e6..b285b2d4 100644
--- a/problems/0024.两两交换链表中的节点.md
+++ b/problems/0024.两两交换链表中的节点.md
@@ -86,6 +86,34 @@ public:
## 其他语言版本
+C:
+```
+/**
+ * Definition for singly-linked list.
+ * struct ListNode {
+ * int val;
+ * struct ListNode *next;
+ * };
+ */
+
+
+struct ListNode* swapPairs(struct ListNode* head){
+ //使用双指针避免使用中间变量
+ typedef struct ListNode ListNode;
+ ListNode *fakehead = (ListNode *)malloc(sizeof(ListNode));
+ fakehead->next = head;
+ ListNode* right = fakehead->next;
+ ListNode* left = fakehead;
+ while(left && right && right->next ){
+ left->next = right->next;
+ right->next = left->next->next;
+ left->next->next = right;
+ left = right;
+ right = left->next;
+ }
+ return fakehead->next;
+}
+```
Java:
From 098bb7b262e57d7c0ae9a51ab484665577835b4f Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Wed, 4 Aug 2021 12:08:00 +0800
Subject: [PATCH 058/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0198.=E6=89=93?=
=?UTF-8?q?=E5=AE=B6=E5=8A=AB=E8=88=8D-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0198.打家劫舍.md | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/problems/0198.打家劫舍.md b/problems/0198.打家劫舍.md
index 63a68c36..5b5863a4 100644
--- a/problems/0198.打家劫舍.md
+++ b/problems/0198.打家劫舍.md
@@ -25,7 +25,7 @@
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
-
+
提示:
@@ -175,6 +175,22 @@ func max(a, b int) int {
}
```
+JavaScript:
+
+```javascript
+const rob = nums => {
+ // 数组长度
+ const len = nums.length;
+ // dp数组初始化
+ const dp = [nums[0], Math.max(nums[0], nums[1])];
+ // 从下标2开始遍历
+ for (let i = 2; i < len; i++) {
+ dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
+ }
+ return dp[len - 1];
+};
+```
+
From 3d880e9ca67afe1b1a2cb19b8d8cba27c1544875 Mon Sep 17 00:00:00 2001
From: SwordsmanYao
Date: Wed, 4 Aug 2021 16:26:02 +0800
Subject: [PATCH 059/138] =?UTF-8?q?[0347.=E5=89=8DK=E4=B8=AA=E9=AB=98?=
=?UTF-8?q?=E9=A2=91=E5=85=83=E7=B4=A0]=20=E6=B7=BB=E5=8A=A0js=E7=89=88?=
=?UTF-8?q?=E6=9C=AC=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0347.前K个高频元素.md | 95 ++++++++++++++++++++++++++++++++++
1 file changed, 95 insertions(+)
diff --git a/problems/0347.前K个高频元素.md b/problems/0347.前K个高频元素.md
index 6b07c258..161df1ad 100644
--- a/problems/0347.前K个高频元素.md
+++ b/problems/0347.前K个高频元素.md
@@ -190,6 +190,101 @@ class Solution:
Go:
+javaScript:
+```js
+/**
+ * @param {number[]} nums
+ * @param {number} k
+ * @return {number[]}
+ */
+var topKFrequent = function(nums, k) {
+ const map = new Map();
+
+ for(const num of nums) {
+ map.set(num, (map.get(num) || 0) + 1);
+ }
+
+ // 创建小顶堆
+ const priorityQueue = new PriorityQueue((a, b) => a[1] - b[1]);
+
+ // entry 是一个长度为2的数组,0位置存储key,1位置存储value
+ for (const entry of map.entries()) {
+ priorityQueue.push(entry);
+ if (priorityQueue.size() > k) {
+ priorityQueue.pop();
+ }
+ }
+
+ const ret = [];
+
+ for(let i = priorityQueue.size() - 1; i >= 0; i--) {
+ ret[i] = priorityQueue.pop()[0];
+ }
+
+ return ret;
+};
+
+
+function PriorityQueue(compareFn) {
+ this.compareFn = compareFn;
+ this.queue = [];
+}
+
+// 添加
+PriorityQueue.prototype.push = function(item) {
+ this.queue.push(item);
+ let index = this.queue.length - 1;
+ let parent = Math.floor((index - 1) / 2);
+ // 上浮
+ while(parent >= 0 && this.compare(parent, index) > 0) {
+ // 交换
+ [this.queue[index], this.queue[parent]] = [this.queue[parent], this.queue[index]];
+ index = parent;
+ parent = Math.floor((index - 1) / 2);
+ }
+}
+
+// 获取堆顶元素并移除
+PriorityQueue.prototype.pop = function() {
+ const ret = this.queue[0];
+
+ // 把最后一个节点移到堆顶
+ this.queue[0] = this.queue.pop();
+
+ let index = 0;
+ // 左子节点下标,left + 1 就是右子节点下标
+ let left = 1;
+ let selectedChild = this.compare(left, left + 1) > 0 ? left + 1 : left;
+
+ // 下沉
+ while(selectedChild !== undefined && this.compare(index, selectedChild) > 0) {
+ // 交换
+ [this.queue[index], this.queue[selectedChild]] = [this.queue[selectedChild], this.queue[index]];
+ index = selectedChild;
+ left = 2 * index + 1;
+ selectedChild = this.compare(left, left + 1) > 0 ? left + 1 : left;
+ }
+
+ return ret;
+}
+
+PriorityQueue.prototype.size = function() {
+ return this.queue.length;
+}
+
+// 使用传入的 compareFn 比较两个位置的元素
+PriorityQueue.prototype.compare = function(index1, index2) {
+ if (this.queue[index1] === undefined) {
+ return 1;
+ }
+ if (this.queue[index2] === undefined) {
+ return -1;
+ }
+
+ return this.compareFn(this.queue[index1], this.queue[index2]);
+}
+```
+
-----------------------
From e222588496db4a8f3a5a6a6fa9550dc96c9b335f Mon Sep 17 00:00:00 2001
From: Kelvin
Date: Wed, 4 Aug 2021 10:01:52 -0400
Subject: [PATCH 060/138] =?UTF-8?q?=E6=9B=B4=E6=96=B0701.=E4=BA=8C?=
=?UTF-8?q?=E5=8F=89=E6=90=9C=E7=B4=A2=E6=A0=91=E4=B8=AD=E7=9A=84=E6=8F=92?=
=?UTF-8?q?=E5=85=A5=E6=93=8D=E4=BD=9C=20Python3=20=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 增加题解中提及到的递归方法 - 无返回值
2. 增加题解中提及到的迭代方法
---
problems/0701.二叉搜索树中的插入操作.md | 58 ++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/problems/0701.二叉搜索树中的插入操作.md b/problems/0701.二叉搜索树中的插入操作.md
index 61027453..1ec80da1 100644
--- a/problems/0701.二叉搜索树中的插入操作.md
+++ b/problems/0701.二叉搜索树中的插入操作.md
@@ -255,7 +255,7 @@ class Solution {
Python:
-递归法
+**递归法** - 有返回值
```python
class Solution:
@@ -268,7 +268,63 @@ class Solution:
root.left = self.insertIntoBST(root.left, val) # 递归创建左子树
return root
```
+**递归法** - 无返回值
+```python
+class Solution:
+ def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
+ if not root:
+ return TreeNode(val)
+ parent = None
+ def __traverse(cur: TreeNode, val: int) -> None:
+ # 在函数运行的同时把新节点插入到该被插入的地方.
+ nonlocal parent
+ if not cur:
+ new_node = TreeNode(val)
+ if parent.val < val:
+ parent.right = new_node
+ else:
+ parent.left = new_node
+ return
+ parent = cur # 重点: parent的作用只有运行到上面if not cur:才会发挥出来.
+ if cur.val < val:
+ __traverse(cur.right, val)
+ else:
+ __traverse(cur.left, val)
+ return
+ __traverse(root, val)
+ return root
+```
+**迭代法**
+与无返回值的递归函数的思路大体一致
+```python
+class Solution:
+ def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
+ if not root:
+ return TreeNode(val)
+ parent = None
+ cur = root
+
+ # 用while循环不断地找新节点的parent
+ while cur:
+ if cur.val < val:
+ parent = cur
+ cur = cur.right
+ elif cur.val > val:
+ parent = cur
+ cur = cur.left
+
+ # 运行到这意味着已经跳出上面的while循环,
+ # 同时意味着新节点的parent已经被找到.
+ # parent已被找到, 新节点已经ready. 把两个节点黏在一起就好了.
+ if parent.val > val:
+ parent.left = TreeNode(val)
+ else:
+ parent.right = TreeNode(val)
+
+ return root
+
+```
Go:
From a0824a84ec24bec4037087ba7084861885463b8f Mon Sep 17 00:00:00 2001
From: fusunx <1102654482@qq.com>
Date: Thu, 5 Aug 2021 08:02:52 +0800
Subject: [PATCH 061/138] =?UTF-8?q?=E8=83=8C=E5=8C=85=E9=97=AE=E9=A2=98?=
=?UTF-8?q?=E7=90=86=E8=AE=BA=E5=9F=BA=E7=A1=80=E5=AE=8C=E5=85=A8=E8=83=8C?=
=?UTF-8?q?=E5=8C=85=20Javascript?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/背包问题理论基础完全背包.md | 31 ++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/problems/背包问题理论基础完全背包.md b/problems/背包问题理论基础完全背包.md
index a5a708cf..2cbc7bb8 100644
--- a/problems/背包问题理论基础完全背包.md
+++ b/problems/背包问题理论基础完全背包.md
@@ -272,7 +272,38 @@ func main() {
fmt.Println(test_CompletePack2(weight, price, 4))
}
```
+Javascript:
+```Javascript
+// 先遍历物品,再遍历背包容量
+function test_completePack1() {
+ let weight = [1, 3, 5]
+ let value = [15, 20, 30]
+ let bagWeight = 4
+ let dp = new Array(bagWeight + 1).fill(0)
+ for(let i = 0; i <= weight.length; i++) {
+ for(let j = weight[i]; j <= bagWeight; j++) {
+ dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i])
+ }
+ }
+ console.log(dp)
+}
+// 先遍历背包容量,再遍历物品
+function test_completePack2() {
+ let weight = [1, 3, 5]
+ let value = [15, 20, 30]
+ let bagWeight = 4
+ let dp = new Array(bagWeight + 1).fill(0)
+ for(let j = 0; j <= bagWeight; j++) {
+ for(let i = 0; i < weight.length; i++) {
+ if (j >= weight[i]) {
+ dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i])
+ }
+ }
+ }
+ console.log(2, dp);
+}
+```
-----------------------
From 993b0795f5af6d9498ee98707eb780ec0c741802 Mon Sep 17 00:00:00 2001
From: ironartisan
Date: Thu, 5 Aug 2021 10:11:00 +0800
Subject: [PATCH 062/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200100.=E7=9B=B8?=
=?UTF-8?q?=E5=90=8C=E7=9A=84=E6=A0=91=20java=E5=92=8Cpython3=E7=89=88?=
=?UTF-8?q?=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0100.相同的树.md | 84 ++++++++++++++++++++++++++++++---------
1 file changed, 66 insertions(+), 18 deletions(-)
diff --git a/problems/0100.相同的树.md b/problems/0100.相同的树.md
index c40f79fd..31a68692 100644
--- a/problems/0100.相同的树.md
+++ b/problems/0100.相同的树.md
@@ -139,29 +139,29 @@ public:
## 迭代法
```C++
-lass Solution {
+class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL) return true;
if (p == NULL || q == NULL) return false;
queue que;
- que.push(p); //
- que.push(q); //
+ que.push(p); // 添加根节点p
+ que.push(q); // 添加根节点q
while (!que.empty()) { //
TreeNode* leftNode = que.front(); que.pop();
TreeNode* rightNode = que.front(); que.pop();
- if (!leftNode && !rightNode) { //
+ if (!leftNode && !rightNode) { // 若p的节点与q的节点都为空
continue;
}
- //
+ // 若p的节点与q的节点有一个为空或p的节点的值与q节点不同
if ((!leftNode || !rightNode || (leftNode->val != rightNode->val))) {
return false;
}
- que.push(leftNode->left); //
- que.push(rightNode->left); //
- que.push(leftNode->right); //
- que.push(rightNode->right); //
+ que.push(leftNode->left); // 添加p节点的左子树节点
+ que.push(rightNode->left); // 添加q节点的左子树节点点
+ que.push(leftNode->right); // 添加p节点的右子树节点
+ que.push(rightNode->right); // 添加q节点的右子树节点
}
return true;
}
@@ -173,23 +173,71 @@ public:
Java:
```java
+// 递归法
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
- if (p == null && q == null) {
- return true;
- } else if (q == null || p == null) {
- return false;
- } else if (q.val != p.val) {
- return false;
- } else {
- return isSameTree(q.left, p.left) && isSameTree(q.right, p.right);
- }
+ if (p == null && q == null) return true;
+ else if (q == null || p == null) return false;
+ else if (q.val != p.val) return false;
+ return isSameTree(q.left, p.left) && isSameTree(q.right, p.right);
}
}
+```
+```java
+// 迭代法
+class Solution {
+ public boolean isSameTree(TreeNode p, TreeNode q) {
+ if(p == null && q == null) return true;
+ if(p == null || q == null) return false;
+ Queue que= new LinkedList();
+ que.offer(p);
+ que.offer(q);
+ while(!que.isEmpty()){
+ TreeNode leftNode = que.poll();
+ TreeNode rightNode = que.poll();
+ if(leftNode == null && rightNode == null) continue;
+ if(leftNode == null || rightNode== null || leftNode.val != rightNode.val) return false;
+ que.offer(leftNode.left);
+ que.offer(rightNode.left);
+ que.offer(leftNode.right);
+ que.offer(rightNode.right);
+ }
+ return true;
+ }
+}
```
Python:
+```python
+# 递归法
+class Solution:
+ def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
+ if not p and not q: return True
+ elif not p or not q: return False
+ elif p.val != q.val: return False
+ return self.isSameTree(p.left, q.left) and self.isSameTree(p.right, q.right)
+```
+```python
+# 迭代法
+class Solution:
+ def isSameTree(self, p: TreeNode, q: TreeNode) -> bool:
+ if not p and not q: return True
+ if not p or not q: return False
+ que = collections.deque()
+ que.append(p)
+ que.append(q)
+ while que:
+ leftNode = que.popleft()
+ rightNode = que.popleft()
+ if not leftNode and not rightNode: continue
+ if not leftNode or not rightNode or leftNode.val != rightNode.val: return False
+ que.append(leftNode.left)
+ que.append(rightNode.left)
+ que.append(leftNode.right)
+ que.append(rightNode.right)
+ return True
+```
Go:
JavaScript:
From 5865faa73a9a33fab1e199bbce96c29f508a378d Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Thu, 5 Aug 2021 10:36:48 +0800
Subject: [PATCH 063/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0337.=E6=89=93?=
=?UTF-8?q?=E5=AE=B6=E5=8A=AB=E8=88=8D=20III-=E5=8A=A8=E6=80=81=E8=A7=84?=
=?UTF-8?q?=E5=88=92-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0337.打家劫舍III.md | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/problems/0337.打家劫舍III.md b/problems/0337.打家劫舍III.md
index 197841e9..780e4aef 100644
--- a/problems/0337.打家劫舍III.md
+++ b/problems/0337.打家劫舍III.md
@@ -368,7 +368,32 @@ class Solution:
return (val1, val2)
```
-Go:
+JavaScript:
+
+> 动态规划
+
+```javascript
+const rob = root => {
+ // 后序遍历函数
+ const postOrder = node => {
+ // 递归出口
+ if (!node) return [0, 0];
+ // 遍历左子树
+ const left = postOrder(node.left);
+ // 遍历右子树
+ const right = postOrder(node.right);
+ // 不偷当前节点,左右子节点都可以偷或不偷,取最大值
+ const DoNot = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
+ // 偷当前节点,左右子节点只能不偷
+ const Do = node.val + left[0] + right[0];
+ // [不偷,偷]
+ return [DoNot, Do];
+ };
+ const res = postOrder(root);
+ // 返回最大值
+ return Math.max(...res);
+};
+```
From 78c1d0209fc1bfcba73d52294b4b11db09f27f8a Mon Sep 17 00:00:00 2001
From: Jack <965555169@qq.com>
Date: Thu, 5 Aug 2021 12:31:25 +0800
Subject: [PATCH 064/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0121.=E4=B9=B0?=
=?UTF-8?q?=E5=8D=96=E8=82=A1=E7=A5=A8=E7=9A=84=E6=9C=80=E4=BD=B3=E6=97=B6?=
=?UTF-8?q?=E6=9C=BA-JavaScript=E7=89=88?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0121.买卖股票的最佳时机.md | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md
index 259fff34..8ad6c8c6 100644
--- a/problems/0121.买卖股票的最佳时机.md
+++ b/problems/0121.买卖股票的最佳时机.md
@@ -313,6 +313,26 @@ func max(a,b int)int {
}
```
+JavaScript:
+
+```javascript
+const maxProfit = prices => {
+ const len = prices.length;
+ // 创建dp数组
+ const dp = new Array(len).fill([0, 0]);
+ // dp数组初始化
+ dp[0] = [-prices[0], 0];
+ for (let i = 1; i < len; i++) {
+ // 更新dp[i]
+ dp[i] = [
+ Math.max(dp[i - 1][0], -prices[i]),
+ Math.max(dp[i - 1][1], prices[i] + dp[i - 1][0]),
+ ];
+ }
+ return dp[len - 1][1];
+};
+```
+
From f351b222a5912d1972504b77c29b966e3be12e74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BD=99=E6=9D=9C=E6=9E=97?=
Date: Thu, 5 Aug 2021 21:48:56 +0800
Subject: [PATCH 065/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A00704.=E4=BA=8C?=
=?UTF-8?q?=E5=88=86=E6=9F=A5=E6=89=BE=20Swift=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
problems/0704.二分查找.md | 54 +++++++++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/problems/0704.二分查找.md b/problems/0704.二分查找.md
index ed0e2eed..1bbb4b4f 100644
--- a/problems/0704.二分查找.md
+++ b/problems/0704.二分查找.md
@@ -352,6 +352,60 @@ def search(nums, target)
end
```
+**Swift:**
+
+```swift
+// (版本一)左闭右闭区间
+func search(nums: [Int], target: Int) -> Int {
+ // 1. 先定义区间。这里的区间是[left, right]
+ var left = 0
+ var right = nums.count - 1
+
+ while left <= right {// 因为taeget是在[left, right]中,包括两个边界值,所以这里的left == right是有意义的
+ // 2. 计算区间中间的下标(如果left、right都比较大的情况下,left + right就有可能会溢出)
+ // let middle = (left + right) / 2
+ // 防溢出:
+ let middle = left + (right - left) / 2
+
+ // 3. 判断
+ if target < nums[middle] {
+ // 当目标在区间左侧,就需要更新右边的边界值,新区间为[left, middle - 1]
+ right = middle - 1
+ } else if target > nums[middle] {
+ // 当目标在区间右侧,就需要更新左边的边界值,新区间为[middle + 1, right]
+ left = middle + 1
+ } else {
+ // 当目标就是在中间,则返回中间值的下标
+ return middle
+ }
+ }
+
+ // 如果找不到目标,则返回-1
+ return -1
+}
+
+// (版本二)左闭右开区间
+func search(nums: [Int], target: Int) -> Int {
+ var left = 0
+ var right = nums.count
+
+ while left < right {
+ let middle = left + ((right - left) >> 1)
+
+ if target < nums[middle] {
+ right = middle
+ } else if target > nums[middle] {
+ left = middle + 1
+ } else {
+ return middle
+ }
+ }
+
+ return -1
+}
+
+```
+
-----------------------
From d2cc6c49da0d56e6036ebfbd686dc573eccbbf09 Mon Sep 17 00:00:00 2001
From: X-shuffle <53906918+X-shuffle@users.noreply.github.com>
Date: Thu, 5 Aug 2021 23:14:59 +0800
Subject: [PATCH 066/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=200406.=E6=A0=B9?=
=?UTF-8?q?=E6=8D=AE=E8=BA=AB=E9=AB=98=E9=87=8D=E5=BB=BA=E9=98=9F=E5=88=97?=
=?UTF-8?q?=20go=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
添加 0406.根据身高重建队列 go版本
---
problems/0406.根据身高重建队列.md | 20 +++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/problems/0406.根据身高重建队列.md b/problems/0406.根据身高重建队列.md
index a5f66a5d..699f67d0 100644
--- a/problems/0406.根据身高重建队列.md
+++ b/problems/0406.根据身高重建队列.md
@@ -217,7 +217,25 @@ class Solution:
```
Go:
-
+```golang
+func reconstructQueue(people [][]int) [][]int {
+ //先将身高从大到小排序,确定最大个子的相对位置
+ sort.Slice(people,func(i,j int)bool{
+ if people[i][0]==people[j][0]{
+ return people[i][1]people[j][0]//这个只是确保身高按照由大到小的顺序来排,并不确定K是按照从小到大排序的
+ })
+ //再按照K进行插入排序,优先插入K小的
+ result := make([][]int, 0)
+ for _, info := range people {
+ result = append(result, info)
+ copy(result[info[1] +1:], result[info[1]:])//将插入位置之后的元素后移动一位(意思是腾出空间)
+ result[info[1]] = info//将插入元素位置插入元素
+ }
+ return result
+}
+```
Javascript:
```Javascript
var reconstructQueue = function(people) {
From b3cf5d46f513cfd1e8ee93067a25a98b4f244c2e Mon Sep 17 00:00:00 2001
From: wjjiang <48505670+Spongecaptain@users.noreply.github.com>
Date: Fri, 6 Aug 2021 09:48:40 +0800
Subject: [PATCH 067/138] =?UTF-8?q?Update=200617.=E5=90=88=E5=B9=B6?=
=?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
添加 Go 的迭代版本
---
problems/0617.合并二叉树.md | 40 +++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/problems/0617.合并二叉树.md b/problems/0617.合并二叉树.md
index 09d844f3..2900a817 100644
--- a/problems/0617.合并二叉树.md
+++ b/problems/0617.合并二叉树.md
@@ -426,6 +426,46 @@ func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
root1.Right = mergeTrees(root1.Right, root2.Right)
return root1
}
+
+// 迭代版本
+func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode {
+ queue := make([]*TreeNode,0)
+ if root1 == nil{
+ return root2
+ }
+ if root2 == nil{
+ return root1
+ }
+ queue = append(queue,root1)
+ queue = append(queue,root2)
+
+ for size:=len(queue);size>0;size=len(queue){
+ node1 := queue[0]
+ queue = queue[1:]
+ node2 := queue[0]
+ queue = queue[1:]
+ node1.Val += node2.Val
+ // 左子树都不为空
+ if node1.Left != nil && node2.Left != nil{
+ queue = append(queue,node1.Left)
+ queue = append(queue,node2.Left)
+ }
+ // 右子树都不为空
+ if node1.Right !=nil && node2.Right !=nil{
+ queue = append(queue,node1.Right)
+ queue = append(queue,node2.Right)
+ }
+ // 树 1 的左子树为 nil,直接接上树 2 的左子树
+ if node1.Left == nil{
+ node1.Left = node2.Left
+ }
+ // 树 1 的右子树为 nil,直接接上树 2 的右子树
+ if node1.Right == nil{
+ node1.Right = node2.Right
+ }
+ }
+ return root1
+}
```
JavaScript:
From 18bf14707c3b75148a07e4c82110df2b07eab5ae Mon Sep 17 00:00:00 2001
From: YDLIN <1924723909@qq.com>
Date: Fri, 6 Aug 2021 10:56:21 +0800
Subject: [PATCH 068/138] =?UTF-8?q?=E6=B7=BB=E5=8A=A00035.=E6=90=9C?=
=?UTF-8?q?=E7=B4=A2=E6=8F=92=E5=85=A5=E4=BD=8D=E7=BD=AE=20Swift=E7=89=88?=
=?UTF-8?q?=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pics/.DS_Store | Bin 6148 -> 0 bytes
problems/0035.搜索插入位置.md | 41 +++++++++++++++++++++++++++++-----
2 files changed, 36 insertions(+), 5 deletions(-)
delete mode 100644 pics/.DS_Store
diff --git a/pics/.DS_Store b/pics/.DS_Store
deleted file mode 100644
index 5008ddfcf53c02e82d7eee2e57c38e5672ef89f6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 6148
zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3
zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ
zLs35+`xjp>T0 Int {
+ for i in 0..= target {
+ return i
+ }
+ }
+ return nums.count
+}
+
+// 二分法
+func searchInsert(_ nums: [Int], _ target: Int) -> Int {
+ var left = 0
+ var right = nums.count - 1
+
+ while left <= right {
+ let middle = left + ((right - left) >> 1)
+
+ if nums[middle] > target {
+ right = middle - 1
+ }else if nums[middle] < target {
+ left = middle + 1
+ }else if nums[middle] == target {
+ return middle
+ }
+ }
+
+ return right + 1
+}
+```
+
+
+
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
From 0f6ffd0d1bf7e968b8f730785eb4f3c083e7dfea Mon Sep 17 00:00:00 2001
From: Nixiak-nan <70318059+Nixiak-nan@users.noreply.github.com>
Date: Fri, 6 Aug 2021 13:40:01 +0800
Subject: [PATCH 069/138] =?UTF-8?q?Update=200513.=E6=89=BE=E6=A0=91?=
=?UTF-8?q?=E5=B7=A6=E4=B8=8B=E8=A7=92=E7=9A=84=E5=80=BC.md?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
增加题目地址
---
problems/0513.找树左下角的值.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/problems/0513.找树左下角的值.md b/problems/0513.找树左下角的值.md
index 27c6e83c..7e48b53c 100644
--- a/problems/0513.找树左下角的值.md
+++ b/problems/0513.找树左下角的值.md
@@ -9,6 +9,8 @@
## 513.找树左下角的值
+题目地址:[https://leetcode-cn.com/problems/find-bottom-left-tree-value/](https://leetcode-cn.com/problems/find-bottom-left-tree-value/v)
+
给定一个二叉树,在树的最后一行找到最左边的值。
示例 1:
From 029cf012eef7729e01bf530fb29ce131bd8ee287 Mon Sep 17 00:00:00 2001
From: youngyangyang04 <826123027@qq.com>
Date: Fri, 6 Aug 2021 15:34:33 +0800
Subject: [PATCH 070/138] Update
---
README.md | 1 +
problems/0072.编辑距离.md | 4 +-
problems/0084.柱状图中最大的矩形.md | 193 ++++++++++
problems/0101.对称二叉树.md | 2 +
problems/0102.二叉树的层序遍历.md | 430 +++++++---------------
problems/0104.二叉树的最大深度.md | 294 ++++++++-------
problems/0110.平衡二叉树.md | 43 +--
problems/0111.二叉树的最小深度.md | 20 +-
problems/0222.完全二叉树的节点个数.md | 57 ++-
problems/0257.二叉树的所有路径.md | 113 +++---
problems/0343.整数拆分.md | 4 +
problems/0941.有效的山脉数组.md | 68 +++-
problems/二叉树中递归带着回溯.md | 6 +-
problems/周总结/20201003二叉树周末总结.md | 4 +-
problems/数组理论基础.md | 2 +-
problems/背包理论基础01背包-1.md | 4 +-
problems/背包理论基础01背包-2.md | 2 +-
problems/背包问题理论基础完全背包.md | 2 +-
18 files changed, 674 insertions(+), 575 deletions(-)
create mode 100644 problems/0084.柱状图中最大的矩形.md
diff --git a/README.md b/README.md
index bbceda2e..1de973a1 100644
--- a/README.md
+++ b/README.md
@@ -409,6 +409,7 @@
2. [单调栈:下一个更大元素I](./problems/0496.下一个更大元素I.md)
3. [单调栈:下一个更大元素II](./problems/0503.下一个更大元素II.md)
4. [单调栈:接雨水](./problems/0042.接雨水.md)
+5. [单调栈:柱状图中最大的矩形](./problems/0084.柱状图中最大的矩形.md)
(持续更新中....)
diff --git a/problems/0072.编辑距离.md b/problems/0072.编辑距离.md
index 9ddca7c0..3a3b584a 100644
--- a/problems/0072.编辑距离.md
+++ b/problems/0072.编辑距离.md
@@ -91,12 +91,12 @@ if (word1[i - 1] != word2[j - 1])
`if (word1[i - 1] != word2[j - 1])`,此时就需要编辑了,如何编辑呢?
-操作一:word1增加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-2为结尾的word1 与 j-1为结尾的word2的最近编辑距离 加上一个增加元素的操作。
+* 操作一:word1增加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-2为结尾的word1 与 j-1为结尾的word2的最近编辑距离 加上一个增加元素的操作。
即 `dp[i][j] = dp[i - 1][j] + 1;`
-操作二:word2添加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个增加元素的操作。
+* 操作二:word2添加一个元素,使其word1[i - 1]与word2[j - 1]相同,那么就是以下标i-1为结尾的word1 与 j-2为结尾的word2的最近编辑距离 加上一个增加元素的操作。
即 `dp[i][j] = dp[i][j - 1] + 1;`
diff --git a/problems/0084.柱状图中最大的矩形.md b/problems/0084.柱状图中最大的矩形.md
new file mode 100644
index 00000000..1abe6623
--- /dev/null
+++ b/problems/0084.柱状图中最大的矩形.md
@@ -0,0 +1,193 @@
+
+
+# 84.柱状图中最大的矩形
+
+链接:https://leetcode-cn.com/problems/largest-rectangle-in-histogram/
+
+给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。
+
+求在该柱状图中,能够勾勒出来的矩形的最大面积。
+
+
+
+
+
+
+# 思路
+
+本题和[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw),是遥相呼应的两道题目,建议都要仔细做一做,原理上有很多相同的地方,但细节上又有差异,更可以加深对单调栈的理解!
+
+其实这两道题目先做那一道都可以,但我先写的42.接雨水的题解,所以如果没做过接雨水的话,建议先做一做接雨水,可以参考我的题解:[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)
+
+我们先来看一下双指针的解法:
+
+## 双指针解法
+
+```C++
+class Solution {
+public:
+ int largestRectangleArea(vector& heights) {
+ int sum = 0;
+ for (int i = 0; i < heights.size(); i++) {
+ int left = i;
+ int right = i;
+ for (; left >= 0; left--) {
+ if (heights[left] < heights[i]) break;
+ }
+ for (; right < heights.size(); right++) {
+ if (heights[right] < heights[i]) break;
+ }
+ int w = right - left - 1;
+ int h = heights[i];
+ sum = max(sum, w * h);
+ }
+ return sum;
+ }
+};
+```
+
+如上代码并不能通过leetcode,超时了,因为时间复杂度是O(n^2)。
+
+## 动态规划
+
+本题动态规划的写法整体思路和[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)是一致的,但要比[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)难一些。
+
+难就难在本题要记录记录每个柱子 左边第一个小于该柱子的下标,而不是左边第一个小于该柱子的高度。
+
+所以需要循环查找,也就是下面在寻找的过程中使用了while,详细请看下面注释,整理思路在题解:[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)中已经介绍了。
+
+```C++
+class Solution {
+public:
+ int largestRectangleArea(vector& heights) {
+ vector minLeftIndex(heights.size());
+ vector minRightIndex(heights.size());
+ int size = heights.size();
+
+ // 记录每个柱子 左边第一个小于该柱子的下标
+ minLeftIndex[0] = -1; // 注意这里初始化,防止下面while死循环
+ for (int i = 1; i < size; i++) {
+ int t = i - 1;
+ // 这里不是用if,而是不断向左寻找的过程
+ while (t >= 0 && heights[t] >= heights[i]) t = minLeftIndex[t];
+ minLeftIndex[i] = t;
+ }
+ // 记录每个柱子 右边第一个小于该柱子的下标
+ minRightIndex[size - 1] = size; // 注意这里初始化,防止下面while死循环
+ for (int i = size - 2; i >= 0; i--) {
+ int t = i + 1;
+ // 这里不是用if,而是不断向右寻找的过程
+ while (t < size && heights[t] >= heights[i]) t = minRightIndex[t];
+ minRightIndex[i] = t;
+ }
+ // 求和
+ int result = 0;
+ for (int i = 0; i < size; i++) {
+ int sum = heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1);
+ result = max(sum, result);
+ }
+ return result;
+ }
+};
+```
+
+## 单调栈
+
+本地单调栈的解法和接雨水的题目是遥相呼应的。
+
+为什么这么说呢,[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)是找每个柱子左右两边第一个大于该柱子高度的柱子,而本题是找每个柱子左右两边第一个小于该柱子的柱子。
+
+**这里就涉及到了单调栈很重要的性质,就是单调栈里的顺序,是从小到大还是从大到小**。
+
+在题解[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)中我讲解了接雨水的单调栈从栈头(元素从栈头弹出)到栈底的顺序应该是从小到大的顺序。
+
+那么因为本题是要找每个柱子左右两边第一个小于该柱子的柱子,所以从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!
+
+我来举一个例子,如图:
+
+
+
+只有栈里从大到小的顺序,才能保证栈顶元素找到左右两边第一个小于栈顶元素的柱子。
+
+所以本题单调栈的顺序正好与接雨水反过来。
+
+此时大家应该可以发现其实就是**栈顶和栈顶的下一个元素以及要入栈的三个元素组成了我们要求最大面积的高度和宽度**
+
+理解这一点,对单调栈就掌握的比较到位了。
+
+除了栈内元素顺序和接雨水不同,剩下的逻辑就都差不多了,在题解[42. 接雨水](https://mp.weixin.qq.com/s/QogENxhotboct9wn7GgYUw)我已经对单调栈的各个方面做了详细讲解,这里就不赘述了。
+
+剩下就是分析清楚如下三种情况:
+
+* 情况一:当前遍历的元素heights[i]小于栈顶元素heights[st.top()]的情况
+* 情况二:当前遍历的元素heights[i]等于栈顶元素heights[st.top()]的情况
+* 情况三:当前遍历的元素heights[i]大于栈顶元素heights[st.top()]的情况
+
+C++代码如下:
+
+```C++
+// 版本一
+class Solution {
+public:
+ int largestRectangleArea(vector& heights) {
+ stack st;
+ heights.insert(heights.begin(), 0); // 数组头部加入元素0
+ heights.push_back(0); // 数组尾部加入元素0
+ st.push(0);
+ int result = 0;
+ // 第一个元素已经入栈,从下表1开始
+ for (int i = 1; i < heights.size(); i++) {
+ // 注意heights[i] 是和heights[st.top()] 比较 ,st.top()是下表
+ if (heights[i] > heights[st.top()]) {
+ st.push(i);
+ } else if (heights[i] == heights[st.top()]) {
+ st.pop(); // 这个可以加,可以不加,效果一样,思路不同
+ st.push(i);
+ } else {
+ while (heights[i] < heights[st.top()]) { // 注意是while
+ int mid = st.top();
+ st.pop();
+ int left = st.top();
+ int right = i;
+ int w = right - left - 1;
+ int h = heights[mid];
+ result = max(result, w * h);
+ }
+ st.push(i);
+ }
+ }
+ return result;
+ }
+};
+
+```
+
+代码精简之后:
+
+```C++
+// 版本二
+class Solution {
+public:
+ int largestRectangleArea(vector& heights) {
+ stack st;
+ heights.insert(heights.begin(), 0); // 数组头部加入元素0
+ heights.push_back(0); // 数组尾部加入元素0
+ st.push(0);
+ int result = 0;
+ for (int i = 1; i < heights.size(); i++) {
+ while (heights[i] < heights[st.top()]) {
+ int mid = st.top();
+ st.pop();
+ int w = i - st.top() - 1;
+ int h = heights[mid];
+ result = max(result, w * h);
+ }
+ st.push(i);
+ }
+ return result;
+ }
+};
+```
+
+这里我依然建议大家按部就班把版本一写出来,把情况一二三分析清楚,然后在精简代码到版本二。 直接看版本二容易忽略细节!
+
diff --git a/problems/0101.对称二叉树.md b/problems/0101.对称二叉树.md
index 241564e9..9f3ceb73 100644
--- a/problems/0101.对称二叉树.md
+++ b/problems/0101.对称二叉树.md
@@ -251,6 +251,8 @@ public:
# 相关题目推荐
+这两道题目基本和本题是一样的,只要稍加修改就可以AC。
+
* 100.相同的树
* 572.另一个树的子树
diff --git a/problems/0102.二叉树的层序遍历.md b/problems/0102.二叉树的层序遍历.md
index 8be3ac47..f63373fc 100644
--- a/problems/0102.二叉树的层序遍历.md
+++ b/problems/0102.二叉树的层序遍历.md
@@ -6,11 +6,8 @@
欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
-# 二叉树的层序遍历
-看完这篇文章虽然不能打十个,但是可以迅速打八个!而且够快!
-
-学会二叉树的层序遍历,可以一口气撸完leetcode上八道题目:
+学会二叉树的层序遍历,可以一口气打完以下十题:
* 102.二叉树的层序遍历
* 107.二叉树的层次遍历II
@@ -20,9 +17,16 @@
* 515.在每个树行中找最大值
* 116.填充每个节点的下一个右侧节点指针
* 117.填充每个节点的下一个右侧节点指针II
+* 104.二叉树的最大深度
+* 111.二叉树的最小深度
+
+在之前写过这篇文章 [二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog),可惜当时只打了5个,还不够,再给我一次机会,我打十个!
+
+
-## 102.二叉树的层序遍历
+
+# 102.二叉树的层序遍历
题目地址:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/
@@ -38,7 +42,6 @@
* [二叉树:前中后序迭代法](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)
* [二叉树:前中后序迭代方式统一写法](https://mp.weixin.qq.com/s/ATQMPCpBlaAgrqdLDMVPZA)
-
接下来我们再来介绍二叉树的另一种遍历方式:层序遍历。
层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。这种遍历的方式和我们之前讲过的都不太一样。
@@ -53,11 +56,11 @@
这样就实现了层序从左到右遍历二叉树。
-代码如下:**这份代码也可以作为二叉树层序遍历的模板,以后再打七个就靠它了**。
+代码如下:**这份代码也可以作为二叉树层序遍历的模板,打十个就靠它了**。
C++代码:
-```
+```C++
class Solution {
public:
vector> levelOrder(TreeNode* root) {
@@ -225,9 +228,10 @@ var levelOrder = function(root) {
```
-**此时我们就掌握了二叉树的层序遍历了,那么如下五道leetcode上的题目,只需要修改模板的一两行代码(不能再多了),便可打倒!**
+**此时我们就掌握了二叉树的层序遍历了,那么如下九道力扣上的题目,只需要修改模板的两三行代码(不能再多了),便可打倒!**
-## 107.二叉树的层次遍历 II
+
+# 107.二叉树的层次遍历 II
题目链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal-ii/
@@ -404,7 +408,7 @@ var levelOrderBottom = function(root) {
```
-## 199.二叉树的右视图
+# 199.二叉树的右视图
题目链接:https://leetcode-cn.com/problems/binary-tree-right-side-view/
@@ -581,7 +585,7 @@ var rightSideView = function(root) {
};
```
-## 637.二叉树的层平均值
+# 637.二叉树的层平均值
题目链接:https://leetcode-cn.com/problems/average-of-levels-in-binary-tree/
@@ -765,7 +769,7 @@ var averageOfLevels = function(root) {
};
```
-## 429.N叉树的层序遍历
+# 429.N叉树的层序遍历
题目链接:https://leetcode-cn.com/problems/n-ary-tree-level-order-traversal/
@@ -985,7 +989,7 @@ var levelOrder = function(root) {
};
```
-## 515.在每个树行中找最大值
+# 515.在每个树行中找最大值
题目链接:https://leetcode-cn.com/problems/find-largest-value-in-each-tree-row/
@@ -1115,7 +1119,7 @@ var largestValues = function(root) {
};
```
-## 116.填充每个节点的下一个右侧节点指针
+# 116.填充每个节点的下一个右侧节点指针
题目链接:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node/
@@ -1254,7 +1258,7 @@ func connect(root *Node) *Node {
}
```
-## 117.填充每个节点的下一个右侧节点指针II
+# 117.填充每个节点的下一个右侧节点指针II
题目地址:https://leetcode-cn.com/problems/populating-next-right-pointers-in-each-node-ii/
@@ -1295,6 +1299,7 @@ public:
}
};
```
+
python代码:
```python
@@ -1378,12 +1383,119 @@ func connect(root *Node) *Node {
return root
}
```
+# 104.二叉树的最大深度
-## 总结
+题目地址:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
-二叉树的层序遍历,就是图论中的广度优先搜索在二叉树中的应用,需要借助队列来实现(此时是不是又发现队列的应用了)。
+给定一个二叉树,找出其最大深度。
-虽然不能一口气打十个,打八个也还行。
+二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
+
+说明: 叶子节点是指没有子节点的节点。
+
+示例:
+
+给定二叉树 [3,9,20,null,null,15,7],
+
+
+
+返回它的最大深度 3 。
+
+思路:
+
+使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。
+
+在二叉树中,一层一层的来遍历二叉树,记录一下遍历的层数就是二叉树的深度,如图所示:
+
+
+
+所以这道题的迭代法就是一道模板题,可以使用二叉树层序遍历的模板来解决的。
+
+C++代码如下:
+
+```C++
+class Solution {
+public:
+ int maxDepth(TreeNode* root) {
+ if (root == NULL) return 0;
+ int depth = 0;
+ queue que;
+ que.push(root);
+ while(!que.empty()) {
+ int size = que.size();
+ depth++; // 记录深度
+ for (int i = 0; i < size; i++) {
+ TreeNode* node = que.front();
+ que.pop();
+ if (node->left) que.push(node->left);
+ if (node->right) que.push(node->right);
+ }
+ }
+ return depth;
+ }
+};
+```
+
+Java:
+
+
+Python:
+
+Go:
+
+JavaScript:
+
+# 111.二叉树的最小深度
+
+相对于 104.二叉树的最大深度 ,本题还也可以使用层序遍历的方式来解决,思路是一样的。
+
+**需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点**
+
+代码如下:(详细注释)
+
+```C++
+class Solution {
+public:
+ int minDepth(TreeNode* root) {
+ if (root == NULL) return 0;
+ int depth = 0;
+ queue que;
+ que.push(root);
+ while(!que.empty()) {
+ int size = que.size();
+ depth++; // 记录最小深度
+ for (int i = 0; i < size; i++) {
+ TreeNode* node = que.front();
+ que.pop();
+ if (node->left) que.push(node->left);
+ if (node->right) que.push(node->right);
+ if (!node->left && !node->right) { // 当左右孩子都为空的时候,说明是最低点的一层了,退出
+ return depth;
+ }
+ }
+ }
+ return depth;
+ }
+};
+```
+
+Java:
+
+
+Python:
+
+Go:
+
+JavaScript:
+
+
+
+
+# 总结
+
+二叉树的层序遍历,**就是图论中的广度优先搜索在二叉树中的应用**,需要借助队列来实现(此时又发现队列的一个应用了)。
+
+来吧,一口气打十个:
* 102.二叉树的层序遍历
* 107.二叉树的层次遍历II
@@ -1393,287 +1505,13 @@ func connect(root *Node) *Node {
* 515.在每个树行中找最大值
* 116.填充每个节点的下一个右侧节点指针
* 117.填充每个节点的下一个右侧节点指针II
+* 104.二叉树的最大深度
+* 111.二叉树的最小深度
-如果非要打十个,还得找叶师傅!
-
-
+**致敬叶师傅!**
-
-# 其他语言版本
-
-
-> 二叉树的层序遍历(Javascript语言完全版) (迭代 + 递归)
-
-```js
-/**
- * 102. 二叉树的层序遍历
- * @param {TreeNode} root
- * @return {number[][]}
- */
-
-// 迭代
-
-var levelOrder = function(root) {
- const queue = [], res = [];
- root && queue.push(root);
- while(len = queue.length) {
- const val = [];
- while(len--) {
- const node = queue.shift();
- val.push(node.val);
- node.left && queue.push(node.left);
- node.right && queue.push(node.right);
- }
- res.push(val);
- }
- return res;
-};
-
-// 递归
-var levelOrder = function(root) {
- const res = [];
- function defs (root, i) {
- if(!root) return;
- if(!res[i]) res[i] = [];
- res[i].push(root.val)
- root.left && defs(root.left, i + 1);
- root.right && defs(root.right, i + 1);
- }
- defs(root, 0);
- return res;
-};
-
-
-/**
- * 107. 二叉树的层序遍历 II
- * @param {TreeNode} root
- * @return {number[][]}
- */
-
-// 迭代
-
-var levelOrderBottom = function(root) {
- const queue = [], res = [];
- root && queue.push(root);
- while(len = queue.length) {
- const val = [];
- while(len--) {
- const node = queue.shift();
- val.push(node.val);
- node.left && queue.push(node.left);
- node.right && queue.push(node.right);
- }
- res.push(val);
- }
- return res.reverse()
-};
-
-// 递归
-
-var levelOrderBottom = function(root) {
- const res = [];
- function defs (root, i) {
- if(!root) return;
- if(!res[i]) res[i] = [];
- res[i].push(root.val);
- root.left && defs(root.left, i + 1);
- root.right && defs(root.right, i + 1);
- }
- defs(root, 0);
- return res.reverse();
-};
-
-/**
- * 199. 二叉树的右视图
- * @param {TreeNode} root
- * @return {number[]}
- */
-
-// 迭代
-
-var rightSideView = function(root) {
- const res = [], queue = [];
- root && queue.push(root);
- while(l = queue.length) {
- while (l--) {
- const {val, left, right} = queue.shift();
- !l && res.push(val);
- left && queue.push(left);
- right && queue.push(right);
- }
- }
- return res;
-};
-
-// 递归
-var rightSideView = function(root) {
- const res = [];
- function defs(root, i) {
- if(!root) return;
- res[i] = root.val;
- root.left && defs(root.left, i + 1);
- root.right && defs(root.right, i + 1);
- }
- defs(root, 0);
- return res;
-};
-
-/**
- * 637. 二叉树的层平均值
- * @param {TreeNode} root
- * @return {number[]}
- */
-
-// 迭代
-var averageOfLevels = function(root) {
- const queue = [], res = [];
- root && queue.push(root);
- while(len = queue.length) {
- let sum = 0, l = len;
- while(l--) {
- const {val, left, right} = queue.shift();
- sum += val;
- left && queue.push(left);
- right && queue.push(right);
- }
- res.push(sum/len);
- }
- return res;
-};
-
-// 递归
-var averageOfLevels = function(root) {
- const resCount = [], res = [];
- function defs(root, i) {
- if(!root) return;
- if(isNaN(res[i])) resCount[i] = res[i] = 0;
- res[i] += root.val;
- resCount[i]++;
- root.left && defs(root.left, i + 1);
- root.right && defs(root.right, i + 1);
- }
- defs(root, 0);
- return res.map((val, i) => val / resCount[i]);
-};
-
-/**
- * 515. 在每个树行中找最大值
- * @param {TreeNode} root
- * @return {number[]}
- */
-
-// 迭代
-const MIN_G = Number.MIN_SAFE_INTEGER;
-var largestValues = function(root) {
- const queue = [], res = [];
- root && queue.push(root);
- while(len = queue.length) {
- let max = MIN_G;
- while(len--) {
- const {val, left, right} = queue.shift();
- max = max > val ? max : val;
- left && queue.push(left);
- right && queue.push(right);
- }
- res.push(max);
- }
- return res;
-};
-
-// 递归
-var largestValues = function(root) {
- const res = [];
- function defs (root, i) {
- if(!root) return;
- if(isNaN(res[i])) res[i] = root.val;
- res[i] = res[i] > root.val ? res[i] : root.val;
- root.left && defs(root.left, i + 1);
- root.right && defs(root.right, i + 1);
- }
- defs(root, 0);
- return res;
-};
-
-/**
- * 429. N 叉树的层序遍历
- * @param {Node|null} root
- * @return {number[][]}
- */
-
-// 迭代
-var levelOrder = function(root) {
- const queue = [], res = [];
- root && queue.push(root);
- while(len = queue.length) {
- const vals = [];
- while(len--) {
- const {val, children} = queue.shift();
- vals.push(val);
- for(const e of children) {
- queue.push(e);
- }
- }
- res.push(vals);
- }
- return res;
-};
-
-// 递归
-
-var levelOrder = function(root) {
- const res = [];
- function defs (root, i) {
- if(!root) return;
- if(!res[i]) res[i] = [];
- res[i].push(root.val);
- for(const e of root.children) {
- defs(e, i + 1);
- }
- }
- defs(root, 0);
- return res;
-};
-
-/**
- * 116. 填充每个节点的下一个右侧节点指针
- * 117. 填充每个节点的下一个右侧节点指针 II
- * @param {Node} root
- * @return {Node}
- */
-
-// 迭代
-var connect = function(root) {
- const queue = [];
- root && queue.push(root);
- while(len = queue.length) {
- while(len--) {
- const node1 = queue.shift(),
- node2 = len ? queue[0] : null;
- node1.next = node2;
- node1.left && queue.push(node1.left);
- node1.right && queue.push(node1.right);
- }
- }
- return root;
-};
-
-// 递归
-var connect = function(root) {
- const res = [];
- function defs (root, i) {
- if(!root) return;
- if(res[i]) res[i].next = root;
- res[i] = root;
- root.left && defs(root.left, i + 1);
- root.right && defs(root.right, i + 1);
- }
- defs(root, 0);
- return root;
-};
-```
-
-----------------------
* 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw)
* B站视频:[代码随想录](https://space.bilibili.com/525438321)
diff --git a/problems/0104.二叉树的最大深度.md b/problems/0104.二叉树的最大深度.md
index 218a966c..252f9e61 100644
--- a/problems/0104.二叉树的最大深度.md
+++ b/problems/0104.二叉树的最大深度.md
@@ -8,10 +8,11 @@
看完本篇可以一起做了如下两道题目:
-* 104.二叉树的最大深度
-* 559.N叉树的最大深度
-## 104.二叉树的最大深度
+* 104.二叉树的最大深度
+* 559.n叉树的最大深度
+
+# 104.二叉树的最大深度
题目地址:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
@@ -28,7 +29,7 @@
返回它的最大深度 3 。
-### 递归法
+## 递归法
本题可以使用前序(中左右),也可以使用后序遍历(左右中),使用前序求的就是深度,使用后序求的是高度。
@@ -41,53 +42,53 @@
1. 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回这棵树的深度,所以返回值为int类型。
代码如下:
-```
-int getDepth(TreeNode* node)
+```c++
+int getdepth(treenode* node)
```
2. 确定终止条件:如果为空节点的话,就返回0,表示高度为0。
代码如下:
-```
-if (node == NULL) return 0;
+```c++
+if (node == null) return 0;
```
3. 确定单层递归的逻辑:先求它的左子树的深度,再求的右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。
代码如下:
-```
-int leftDepth = getDepth(node->left); // 左
-int rightDepth = getDepth(node->right); // 右
-int depth = 1 + max(leftDepth, rightDepth); // 中
+```c++
+int leftdepth = getdepth(node->left); // 左
+int rightdepth = getdepth(node->right); // 右
+int depth = 1 + max(leftdepth, rightdepth); // 中
return depth;
```
-所以整体C++代码如下:
+所以整体c++代码如下:
-```C++
-class Solution {
+```c++
+class solution {
public:
- int getDepth(TreeNode* node) {
- if (node == NULL) return 0;
- int leftDepth = getDepth(node->left); // 左
- int rightDepth = getDepth(node->right); // 右
- int depth = 1 + max(leftDepth, rightDepth); // 中
+ int getdepth(treenode* node) {
+ if (node == null) return 0;
+ int leftdepth = getdepth(node->left); // 左
+ int rightdepth = getdepth(node->right); // 右
+ int depth = 1 + max(leftdepth, rightdepth); // 中
return depth;
}
- int maxDepth(TreeNode* root) {
- return getDepth(root);
+ int maxdepth(treenode* root) {
+ return getdepth(root);
}
};
```
-代码精简之后C++代码如下:
-```C++
-class Solution {
+代码精简之后c++代码如下:
+```c++
+class solution {
public:
- int maxDepth(TreeNode* root) {
- if (root == NULL) return 0;
- return 1 + max(maxDepth(root->left), maxDepth(root->right));
+ int maxdepth(treenode* root) {
+ if (root == null) return 0;
+ return 1 + max(maxdepth(root->left), maxdepth(root->right));
}
};
@@ -98,31 +99,31 @@ public:
本题当然也可以使用前序,代码如下:(**充分表现出求深度回溯的过程**)
-```C++
-class Solution {
+```c++
+class solution {
public:
int result;
- void getDepth(TreeNode* node, int depth) {
+ void getdepth(treenode* node, int depth) {
result = depth > result ? depth : result; // 中
- if (node->left == NULL && node->right == NULL) return ;
+ if (node->left == null && node->right == null) return ;
if (node->left) { // 左
depth++; // 深度+1
- getDepth(node->left, depth);
+ getdepth(node->left, depth);
depth--; // 回溯,深度-1
}
if (node->right) { // 右
depth++; // 深度+1
- getDepth(node->right, depth);
+ getdepth(node->right, depth);
depth--; // 回溯,深度-1
}
return ;
}
- int maxDepth(TreeNode* root) {
+ int maxdepth(treenode* root) {
result = 0;
if (root == 0) return result;
- getDepth(root, 1);
+ getdepth(root, 1);
return result;
}
};
@@ -132,31 +133,31 @@ public:
注意以上代码是为了把细节体现出来,简化一下代码如下:
-```C++
-class Solution {
+```c++
+class solution {
public:
int result;
- void getDepth(TreeNode* node, int depth) {
+ void getdepth(treenode* node, int depth) {
result = depth > result ? depth : result; // 中
- if (node->left == NULL && node->right == NULL) return ;
+ if (node->left == null && node->right == null) return ;
if (node->left) { // 左
- getDepth(node->left, depth + 1);
+ getdepth(node->left, depth + 1);
}
if (node->right) { // 右
- getDepth(node->right, depth + 1);
+ getdepth(node->right, depth + 1);
}
return ;
}
- int maxDepth(TreeNode* root) {
+ int maxdepth(treenode* root) {
result = 0;
if (root == 0) return result;
- getDepth(root, 1);
+ getdepth(root, 1);
return result;
}
};
```
-### 迭代法
+## 迭代法
使用迭代法的话,使用层序遍历是最为合适的,因为最大的深度就是二叉树的层数,和层序遍历的方式极其吻合。
@@ -166,23 +167,23 @@ public:
所以这道题的迭代法就是一道模板题,可以使用二叉树层序遍历的模板来解决的。
-如果对层序遍历还不清楚的话,可以看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)
+如果对层序遍历还不清楚的话,可以看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/4-bDKi7SdwfBGRm9FYduiA)
-C++代码如下:
+c++代码如下:
-```C++
-class Solution {
+```c++
+class solution {
public:
- int maxDepth(TreeNode* root) {
- if (root == NULL) return 0;
+ int maxdepth(treenode* root) {
+ if (root == null) return 0;
int depth = 0;
- queue que;
+ queue que;
que.push(root);
while(!que.empty()) {
int size = que.size();
depth++; // 记录深度
for (int i = 0; i < size; i++) {
- TreeNode* node = que.front();
+ treenode* node = que.front();
que.pop();
if (node->left) que.push(node->left);
if (node->right) que.push(node->right);
@@ -193,19 +194,19 @@ public:
};
```
-那么我们可以顺便解决一下N叉树的最大深度问题
+那么我们可以顺便解决一下n叉树的最大深度问题
-## 559.N叉树的最大深度
+# 559.n叉树的最大深度
题目地址:https://leetcode-cn.com/problems/maximum-depth-of-n-ary-tree/
-给定一个 N 叉树,找到其最大深度。
+给定一个 n 叉树,找到其最大深度。
最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。
例如,给定一个 3叉树 :
-
+
我们应返回其最大深度,3。
@@ -213,39 +214,39 @@ public:
依然可以提供递归法和迭代法,来解决这个问题,思路是和二叉树思路一样的,直接给出代码如下:
-### 递归法
+## 递归法
-C++代码:
+c++代码:
-```C++
-class Solution {
+```c++
+class solution {
public:
- int maxDepth(Node* root) {
+ int maxdepth(node* root) {
if (root == 0) return 0;
int depth = 0;
for (int i = 0; i < root->children.size(); i++) {
- depth = max (depth, maxDepth(root->children[i]));
+ depth = max (depth, maxdepth(root->children[i]));
}
return depth + 1;
}
};
```
-### 迭代法
+## 迭代法
依然是层序遍历,代码如下:
-```C++
-class Solution {
+```c++
+class solution {
public:
- int maxDepth(Node* root) {
- queue que;
- if (root != NULL) que.push(root);
+ int maxdepth(node* root) {
+ queue que;
+ if (root != null) que.push(root);
int depth = 0;
while (!que.empty()) {
int size = que.size();
depth++; // 记录深度
for (int i = 0; i < size; i++) {
- Node* node = que.front();
+ node* node = que.front();
que.pop();
for (int j = 0; j < node->children.size(); j++) {
if (node->children[j]) que.push(node->children[j]);
@@ -257,45 +258,46 @@ public:
};
```
-## 其他语言版本
+# 其他语言版本
+## java
-Java:
+### 104.二叉树的最大深度
-```Java
-class Solution {
+```java
+class solution {
/**
* 递归法
*/
- public int maxDepth(TreeNode root) {
+ public int maxdepth(treenode root) {
if (root == null) {
return 0;
}
- int leftDepth = maxDepth(root.left);
- int rightDepth = maxDepth(root.right);
- return Math.max(leftDepth, rightDepth) + 1;
+ int leftdepth = maxdepth(root.left);
+ int rightdepth = maxdepth(root.right);
+ return math.max(leftdepth, rightdepth) + 1;
}
}
```
-```Java
-class Solution {
+```java
+class solution {
/**
* 迭代法,使用层序遍历
*/
- public int maxDepth(TreeNode root) {
+ public int maxdepth(treenode root) {
if(root == null) {
return 0;
}
- Deque deque = new LinkedList<>();
+ deque deque = new linkedlist<>();
deque.offer(root);
int depth = 0;
- while (!deque.isEmpty()) {
+ while (!deque.isempty()) {
int size = deque.size();
depth++;
for (int i = 0; i < size; i++) {
- TreeNode poll = deque.poll();
+ treenode poll = deque.poll();
if (poll.left != null) {
deque.offer(poll.left);
}
@@ -309,37 +311,39 @@ class Solution {
}
```
-Python:
+## python
-104.二叉树的最大深度
-> 递归法:
+### 104.二叉树的最大深度
+
+递归法:
```python
-class Solution:
- def maxDepth(self, root: TreeNode) -> int:
- return self.getDepth(root)
+class solution:
+ def maxdepth(self, root: treenode) -> int:
+ return self.getdepth(root)
- def getDepth(self, node):
+ def getdepth(self, node):
if not node:
return 0
- leftDepth = self.getDepth(node.left) #左
- rightDepth = self.getDepth(node.right) #右
- depth = 1 + max(leftDepth, rightDepth) #中
+ leftdepth = self.getdepth(node.left) #左
+ rightdepth = self.getdepth(node.right) #右
+ depth = 1 + max(leftdepth, rightdepth) #中
return depth
```
-> 递归法;精简代码
+
+递归法:精简代码
```python
-class Solution:
- def maxDepth(self, root: TreeNode) -> int:
+class solution:
+ def maxdepth(self, root: treenode) -> int:
if not root:
return 0
- return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right))
+ return 1 + max(self.maxdepth(root.left), self.maxdepth(root.right))
```
-> 迭代法:
+迭代法:
```python
import collections
-class Solution:
- def maxDepth(self, root: TreeNode) -> int:
+class solution:
+ def maxdepth(self, root: treenode) -> int:
if not root:
return 0
depth = 0 #记录深度
@@ -357,24 +361,25 @@ class Solution:
return depth
```
-559.N叉树的最大深度
-> 递归法:
+### 559.n叉树的最大深度
+
+递归法:
```python
-class Solution:
- def maxDepth(self, root: 'Node') -> int:
+class solution:
+ def maxdepth(self, root: 'node') -> int:
if not root:
return 0
depth = 0
for i in range(len(root.children)):
- depth = max(depth, self.maxDepth(root.children[i]))
+ depth = max(depth, self.maxdepth(root.children[i]))
return depth + 1
```
-> 迭代法:
+迭代法:
```python
import collections
-class Solution:
- def maxDepth(self, root: 'Node') -> int:
+class solution:
+ def maxdepth(self, root: 'node') -> int:
queue = collections.deque()
if root:
queue.append(root)
@@ -390,10 +395,10 @@ class Solution:
return depth
```
-> 使用栈来模拟后序遍历依然可以
+使用栈来模拟后序遍历依然可以
```python
-class Solution:
- def maxDepth(self, root: 'Node') -> int:
+class solution:
+ def maxdepth(self, root: 'node') -> int:
st = []
if root:
st.append(root)
@@ -401,9 +406,9 @@ class Solution:
result = 0
while st:
node = st.pop()
- if node != None:
+ if node != none:
st.append(node) #中
- st.append(None)
+ st.append(none)
depth += 1
for i in range(len(node.children)): #处理孩子
if node.children[i]:
@@ -417,15 +422,15 @@ class Solution:
```
-Go:
+## go
```go
/**
- * Definition for a binary tree node.
- * type TreeNode struct {
- * Val int
- * Left *TreeNode
- * Right *TreeNode
+ * definition for a binary tree node.
+ * type treenode struct {
+ * val int
+ * left *treenode
+ * right *treenode
* }
*/
func max (a, b int) int {
@@ -435,28 +440,28 @@ func max (a, b int) int {
return b;
}
// 递归
-func maxDepth(root *TreeNode) int {
+func maxdepth(root *treenode) int {
if root == nil {
return 0;
}
- return max(maxDepth(root.Left), maxDepth(root.Right)) + 1;
+ return max(maxdepth(root.left), maxdepth(root.right)) + 1;
}
// 遍历
-func maxDepth(root *TreeNode) int {
+func maxdepth(root *treenode) int {
levl := 0;
- queue := make([]*TreeNode, 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.left != nil {
+ queue = append(queue, node.left);
}
- if node.Right != nil {
- queue = append(queue, node.Right);
+ if node.right != nil {
+ queue = append(queue, node.right);
}
queue = queue[1:];
}
@@ -469,46 +474,49 @@ func maxDepth(root *TreeNode) int {
```
-JavaScript
+## javascript
+
```javascript
-var maxDepth = function(root) {
+var maxdepth = function(root) {
if (!root) return root
- return 1 + Math.max(maxDepth(root.left), maxDepth(root.right))
+ return 1 + math.max(maxdepth(root.left), maxdepth(root.right))
};
-```
+```
+
二叉树最大深度递归遍历
```javascript
-var maxDepth = function(root) {
+var maxdepth = function(root) {
//使用递归的方法 递归三部曲
//1. 确定递归函数的参数和返回值
- const getDepth=function(node){
+ const getdepth=function(node){
//2. 确定终止条件
if(node===null){
return 0;
}
//3. 确定单层逻辑
- let leftDepth=getDepth(node.left);
- let rightDepth=getDepth(node.right);
- let depth=1+Math.max(leftDepth,rightDepth);
+ let leftdepth=getdepth(node.left);
+ let rightdepth=getdepth(node.right);
+ let depth=1+math.max(leftdepth,rightdepth);
return depth;
}
- return getDepth(root);
+ return getdepth(root);
};
```
+
二叉树最大深度层级遍历
```javascript
-var maxDepth = function(root) {
+var maxdepth = function(root) {
//使用递归的方法 递归三部曲
//1. 确定递归函数的参数和返回值
- const getDepth=function(node){
+ const getdepth=function(node){
//2. 确定终止条件
if(node===null){
return 0;
}
//3. 确定单层逻辑
- let leftDepth=getDepth(node.left);
- let rightDepth=getDepth(node.right);
- let depth=1+Math.max(leftDepth,rightDepth);
+ let leftdepth=getdepth(node.left);
+ let rightdepth=getdepth(node.right);
+ let depth=1+math.max(leftdepth,rightdepth);
return depth;
}
return getDepth(root);
diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md
index b6e50853..324b3678 100644
--- a/problems/0110.平衡二叉树.md
+++ b/problems/0110.平衡二叉树.md
@@ -9,7 +9,7 @@
> 求高度还是求深度,你搞懂了不?
-## 110.平衡二叉树
+# 110.平衡二叉树
题目地址:https://leetcode-cn.com/problems/balanced-binary-tree/
@@ -33,9 +33,10 @@
返回 false 。
-## 题外话
+# 题外话
-咋眼一看这道题目和[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)很像,其实有很大区别。
+
+咋眼一看这道题目和[104.二叉树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw)很像,其实有很大区别。
这里强调一波概念:
@@ -50,11 +51,11 @@
因为求深度可以从上到下去查 所以需要前序遍历(中左右),而高度只能从下到上去查,所以只能后序遍历(左右中)
-有的同学一定疑惑,为什么[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)中求的是二叉树的最大深度,也用的是后序遍历。
+有的同学一定疑惑,为什么[104.二叉树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw)中求的是二叉树的最大深度,也用的是后序遍历。
**那是因为代码的逻辑其实是求的根节点的高度,而根节点的高度就是这颗树的最大深度,所以才可以使用后序遍历。**
-在[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)中,如果真正求取二叉树的最大深度,代码应该写成如下:(前序遍历)
+在[104.二叉树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw)中,如果真正求取二叉树的最大深度,代码应该写成如下:(前序遍历)
```C++
class Solution {
@@ -114,9 +115,9 @@ public:
};
```
-## 本题思路
+# 本题思路
-### 递归
+## 递归
此时大家应该明白了既然要求比较高度,必然是要后序遍历。
@@ -160,7 +161,7 @@ if (node == NULL) {
代码如下:
-```
+```C++
int leftDepth = depth(node->left); // 左
if (leftDepth == -1) return -1;
int rightDepth = depth(node->right); // 右
@@ -178,7 +179,7 @@ return result;
代码精简之后如下:
-```
+```C++
int leftDepth = getDepth(node->left);
if (leftDepth == -1) return -1;
int rightDepth = getDepth(node->right);
@@ -225,9 +226,9 @@ public:
};
```
-### 迭代
+## 迭代
-在[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)中我们可以使用层序遍历来求深度,但是就不能直接用层序遍历来求高度了,这就体现出求高度和求深度的不同。
+在[104.二叉树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw)中我们可以使用层序遍历来求深度,但是就不能直接用层序遍历来求高度了,这就体现出求高度和求深度的不同。
本题的迭代方式可以先定义一个函数,专门用来求高度。
@@ -266,7 +267,7 @@ int getDepth(TreeNode* cur) {
然后再用栈来模拟前序遍历,遍历每一个节点的时候,再去判断左右孩子的高度是否符合,代码如下:
-```
+```C++
bool isBalanced(TreeNode* root) {
stack st;
if (root == NULL) return true;
@@ -286,7 +287,7 @@ bool isBalanced(TreeNode* root) {
整体代码如下:
-```
+```C++
class Solution {
private:
int getDepth(TreeNode* cur) {
@@ -342,7 +343,7 @@ public:
因为对于回溯算法已经是非常复杂的递归了,如果在用迭代的话,就是自己给自己找麻烦,效率也并不一定高。
-## 总结
+# 总结
通过本题可以了解求二叉树深度 和 二叉树高度的差异,求深度适合用前序遍历,而求高度适合用后序遍历。
@@ -351,9 +352,9 @@ public:
但是递归方式是一定要掌握的!
-## 其他语言版本
+# 其他语言版本
-Java:
+## Java
```Java
class Solution {
@@ -494,9 +495,9 @@ class Solution {
}
```
-Python:
+## Python
-> 递归法:
+递归法:
```python
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
@@ -513,7 +514,7 @@ class Solution:
return -1 if abs(leftDepth - rightDepth)>1 else 1 + max(leftDepth, rightDepth)
```
-> 迭代法:
+迭代法:
```python
class Solution:
def isBalanced(self, root: TreeNode) -> bool:
@@ -553,7 +554,7 @@ class Solution:
```
-Go:
+## Go
```Go
func isBalanced(root *TreeNode) bool {
if root==nil{
@@ -589,7 +590,7 @@ func abs(a int)int{
}
```
-JavaScript:
+## JavaScript
```javascript
var isBalanced = function(root) {
//还是用递归三部曲 + 后序遍历 左右中 当前左子树右子树高度相差大于1就返回-1
diff --git a/problems/0111.二叉树的最小深度.md b/problems/0111.二叉树的最小深度.md
index a36faeff..2ef380ab 100644
--- a/problems/0111.二叉树的最小深度.md
+++ b/problems/0111.二叉树的最小深度.md
@@ -9,7 +9,7 @@
> 和求最大深度一个套路?
-## 111.二叉树的最小深度
+# 111.二叉树的最小深度
题目地址:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/
@@ -27,9 +27,9 @@
返回它的最小深度 2.
-## 思路
+# 思路
-看完了这篇[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg),再来看看如何求最小深度。
+看完了这篇[104.二叉树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw),再来看看如何求最小深度。
直觉上好像和求最大深度差不多,其实还是差不少的。
@@ -154,9 +154,9 @@ public:
## 迭代法
-相对于[104.二叉树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg),本题还可以使用层序遍历的方式来解决,思路是一样的。
+相对于[104.二叉树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw),本题还可以使用层序遍历的方式来解决,思路是一样的。
-如果对层序遍历还不清楚的话,可以看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)
+如果对层序遍历还不清楚的话,可以看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/4-bDKi7SdwfBGRm9FYduiA)
**需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点**
@@ -190,10 +190,10 @@ public:
```
-## 其他语言版本
+# 其他语言版本
-Java:
+## Java
```Java
class Solution {
@@ -253,7 +253,7 @@ class Solution {
}
```
-Python:
+## Python
递归法:
@@ -299,7 +299,7 @@ class Solution:
```
-Go:
+## Go
```go
/**
@@ -360,7 +360,7 @@ func minDepth(root *TreeNode) int {
```
-JavaScript:
+## JavaScript
递归法:
diff --git a/problems/0222.完全二叉树的节点个数.md b/problems/0222.完全二叉树的节点个数.md
index ec68b6c6..c9319372 100644
--- a/problems/0222.完全二叉树的节点个数.md
+++ b/problems/0222.完全二叉树的节点个数.md
@@ -7,24 +7,23 @@
欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!
-## 222.完全二叉树的节点个数
+# 222.完全二叉树的节点个数
题目地址:https://leetcode-cn.com/problems/count-complete-tree-nodes/
给出一个完全二叉树,求出该树的节点个数。
-示例:
示例 1:
-输入:root = [1,2,3,4,5,6]
-输出:6
+* 输入:root = [1,2,3,4,5,6]
+* 输出:6
示例 2:
-输入:root = []
-输出:0
+* 输入:root = []
+* 输出:0
示例 3:
-输入:root = [1]
-输出:1
+* 输入:root = [1]
+* 输出:1
提示:
@@ -33,21 +32,22 @@
* 题目数据保证输入的树是 完全二叉树
-## 思路
+# 思路
本篇给出按照普通二叉树的求法以及利用完全二叉树性质的求法。
+
## 普通二叉树
首先按照普通二叉树的逻辑来求。
-这道题目的递归法和求二叉树的深度写法类似, 而迭代法,[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)遍历模板稍稍修改一下,记录遍历的节点数量就可以了。
+这道题目的递归法和求二叉树的深度写法类似, 而迭代法,[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/4-bDKi7SdwfBGRm9FYduiA)遍历模板稍稍修改一下,记录遍历的节点数量就可以了。
递归遍历的顺序依然是后序(左右中)。
### 递归
-如果对求二叉树深度还不熟悉的话,看这篇:[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/guKwV-gSNbA1CcbvkMtHBg)。
+如果对求二叉树深度还不熟悉的话,看这篇:[二叉树:看看这些树的最大深度](https://mp.weixin.qq.com/s/jRaRcRerhEHepQbt-aKstw)。
1. 确定递归函数的参数和返回值:参数就是传入树的根节点,返回就返回以该节点为根节点二叉树的节点数量,所以返回值为int类型。
@@ -107,15 +107,15 @@ public:
};
```
-时间复杂度:O(n)
-空间复杂度:O(logn),算上了递归系统栈占用的空间
+* 时间复杂度:O(n)
+* 空间复杂度:O(logn),算上了递归系统栈占用的空间
**网上基本都是这个精简的代码版本,其实不建议大家照着这个来写,代码确实精简,但隐藏了一些内容,连遍历的顺序都看不出来,所以初学者建议学习版本一的代码,稳稳的打基础**。
### 迭代法
-如果对求二叉树层序遍历还不熟悉的话,看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/Gb3BjakIKGNpup2jYtTzog)。
+如果对求二叉树层序遍历还不熟悉的话,看这篇:[二叉树:层序遍历登场!](https://mp.weixin.qq.com/s/4-bDKi7SdwfBGRm9FYduiA)。
那么只要模板少做改动,加一个变量result,统计节点数量就可以了
@@ -140,12 +140,12 @@ public:
}
};
```
-时间复杂度:O(n)
-空间复杂度:O(n)
+* 时间复杂度:O(n)
+* 空间复杂度:O(n)
## 完全二叉树
-以上方法都是按照普通二叉树来做的,对于完全二叉树特性不了解的同学可以看这篇 [关于二叉树,你该了解这些!](https://mp.weixin.qq.com/s/_ymfWYvTNd2GvWvC5HOE4A),这篇详细介绍了各种二叉树的特性。
+以上方法都是按照普通二叉树来做的,对于完全二叉树特性不了解的同学可以看这篇 [关于二叉树,你该了解这些!](https://mp.weixin.qq.com/s/q_eKfL8vmSbSFcptZ3aeRA),这篇详细介绍了各种二叉树的特性。
完全二叉树只有两种情况,情况一:就是满二叉树,情况二:最后一层叶子节点没有满。
@@ -187,13 +187,12 @@ public:
};
```
-时间复杂度:O(logn * logn)
-空间复杂度:O(logn)
+* 时间复杂度:O(logn * logn)
+* 空间复杂度:O(logn)
-## 其他语言版本
+# 其他语言版本
-
-Java:
+## Java
```java
class Solution {
// 通用递归解法
@@ -238,9 +237,9 @@ class Solution {
}
```
-Python:
+## Python
-> 递归法:
+递归法:
```python
class Solution:
def countNodes(self, root: TreeNode) -> int:
@@ -255,7 +254,7 @@ class Solution:
return treeNum
```
-> 递归法:精简版
+递归法:精简版
```python
class Solution:
def countNodes(self, root: TreeNode) -> int:
@@ -264,7 +263,7 @@ class Solution:
return 1 + self.countNodes(root.left) + self.countNodes(root.right)
```
-> 迭代法:
+迭代法:
```python
import collections
class Solution:
@@ -285,7 +284,7 @@ class Solution:
return result
```
-> 完全二叉树
+完全二叉树
```python
class Solution:
def countNodes(self, root: TreeNode) -> int:
@@ -306,7 +305,7 @@ class Solution:
return self.countNodes(root.left) + self.countNodes(root.right) + 1
```
-Go:
+## Go
递归版本
@@ -361,7 +360,7 @@ func countNodes(root *TreeNode) int {
-JavaScript:
+## JavaScript:
递归版本
```javascript
diff --git a/problems/0257.二叉树的所有路径.md b/problems/0257.二叉树的所有路径.md
index ce596396..bb0513de 100644
--- a/problems/0257.二叉树的所有路径.md
+++ b/problems/0257.二叉树的所有路径.md
@@ -9,7 +9,7 @@
> 以为只用了递归,其实还用了回溯
-## 257. 二叉树的所有路径
+# 257. 二叉树的所有路径
题目地址:https://leetcode-cn.com/problems/binary-tree-paths/
@@ -20,7 +20,7 @@
示例:

-## 思路
+# 思路
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。
@@ -215,8 +215,52 @@ public:
那么在如上代码中,**貌似没有看到回溯的逻辑,其实不然,回溯就隐藏在`traversal(cur->left, path + "->", result);`中的 `path + "->"`。** 每次函数调用完,path依然是没有加上"->" 的,这就是回溯了。
-**如果这里还不理解的话,可以看这篇[二叉树:以为使用了递归,其实还隐藏着回溯](https://mp.weixin.qq.com/s/ivLkHzWdhjQQD1rQWe6zWA),我这这篇中详细的解释了递归中如何隐藏着回溯。 **
+为了把这份精简代码的回溯过程展现出来,大家可以试一试把:
+```C++
+if (cur->left) traversal(cur->left, path + "->", result); // 左 回溯就隐藏在这里
+```
+
+改成如下代码:
+
+```C++
+path += "->";
+traversal(cur->left, path, result); // 左
+```
+
+即:
+
+```C++
+if (cur->left) {
+ path += "->";
+ traversal(cur->left, path, result); // 左
+}
+if (cur->right) {
+ path += "->";
+ traversal(cur->right, path, result); // 右
+}
+```
+
+此时就没有回溯了,这个代码就是通过不了的了。
+
+如果想把回溯加上,就要 在上面代码的基础上,加上回溯,就可以AC了。
+
+```C++
+if (cur->left) {
+ path += "->";
+ traversal(cur->left, path, result); // 左
+ path.pop_back(); // 回溯
+ path.pop_back();
+}
+if (cur->right) {
+ path += "->";
+ traversal(cur->right, path, result); // 右
+ path.pop_back(); // 回溯
+ path.pop_back();
+}
+```
+
+**大家应该可以感受出来,如果把 `path + "->"`作为函数参数就是可以的,因为并有没有改变path的数值,执行完递归函数之后,path依然是之前的数值(相当于回溯了)**
**综合以上,第二种递归的代码虽然精简但把很多重要的点隐藏在了代码细节里,第一种递归写法虽然代码多一些,但是把每一个逻辑处理都完整的展现了出来了。**
@@ -225,7 +269,8 @@ public:
## 迭代法
-至于非递归的方式,我们可以依然可以使用前序遍历的迭代方式来模拟遍历路径的过程,对该迭代方式不了解的同学,可以看文章[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/c_zCrGHIVlBjUH_hJtghCg)和[二叉树:前中后序迭代方式的写法就不能统一一下么?](https://mp.weixin.qq.com/s/WKg0Ty1_3SZkztpHubZPRg)。
+
+至于非递归的方式,我们可以依然可以使用前序遍历的迭代方式来模拟遍历路径的过程,对该迭代方式不了解的同学,可以看文章[二叉树:听说递归能做的,栈也能做!](https://mp.weixin.qq.com/s/OH7aCVJ5-Gi32PkNCoZk4A)和[二叉树:前中后序迭代方式统一写法](https://mp.weixin.qq.com/s/ATQMPCpBlaAgrqdLDMVPZA)。
这里除了模拟递归需要一个栈,同时还需要一个栈来存放对应的遍历路径。
@@ -262,7 +307,7 @@ public:
```
当然,使用java的同学,可以直接定义一个成员变量为object的栈`Stack