diff --git a/lcci/01.05.One Away/README.md b/lcci/01.05.One Away/README.md index 471c6c5f9190c..762e58c78330d 100644 --- a/lcci/01.05.One Away/README.md +++ b/lcci/01.05.One Away/README.md @@ -43,13 +43,13 @@ second = "pal" ### 方法一:分情况讨论 + 双指针 -我们将字符串 $first$ 和 $second$ 的长度记为 $m$ 和 $n$,不妨设 $m \geq n$。 +我们将字符串 $\textit{first}$ 和 $\textit{second}$ 的长度记为 $m$ 和 $n$,不妨设 $m \geq n$。 接下来分情况讨论: -- 当 $m - n \gt 1$ 时,$first$ 和 $second$ 无法通过一次编辑得到,返回 `false`; -- 当 $m = n$ 时,$first$ 和 $second$ 只有在且仅在有且仅有一个字符不同的情况下才能通过一次编辑得到; -- 当 $m - n = 1$ 时,$first$ 和 $second$ 只有在且仅在 $second$ 是 $first$ 删除一个字符后得到的情况下才能通过一次编辑得到,我们可以使用双指针来实现。 +- 当 $m - n \gt 1$ 时,$\textit{first}$ 和 $\textit{second}$ 无法通过一次编辑得到,返回 `false`; +- 当 $m = n$ 时,$\textit{first}$ 和 $\textit{second}$ 只有在且仅在有且仅有一个字符不同的情况下才能通过一次编辑得到; +- 当 $m - n = 1$ 时,$\textit{first}$ 和 $\textit{second}$ 只有在且仅在 $\textit{second}$ 是 $\textit{first}$ 删除一个字符后得到的情况下才能通过一次编辑得到,我们可以使用双指针来实现。 时间复杂度 $O(n)$,其中 $n$ 为字符串长度。空间复杂度 $O(1)$。 diff --git a/lcci/01.05.One Away/README_EN.md b/lcci/01.05.One Away/README_EN.md index a0703be7fa38b..98a164c97d143 100644 --- a/lcci/01.05.One Away/README_EN.md +++ b/lcci/01.05.One Away/README_EN.md @@ -50,15 +50,15 @@ second = "pal" -### Solution 1: Case Discussion + Two Pointers +### Solution 1: Case Analysis + Two Pointers -We denote the lengths of strings $first$ and $second$ as $m$ and $n$, respectively, where $m \geq n$. +Let the lengths of the strings $\textit{first}$ and $\textit{second}$ be $m$ and $n$, respectively. Assume $m \geq n$. -Next, we discuss different cases: +Next, we discuss the following cases: -- When $m - n > 1$, $first$ and $second$ cannot be obtained through a single edit, so we return `false`. -- When $m = n$, $first$ and $second$ can only be obtained through a single edit if and only if exactly one character is different. -- When $m - n = 1$, $first$ and $second$ can only be obtained through a single edit if and only if $second$ is obtained by deleting one character from $first$. We can use two pointers to implement this. +- When $m - n \gt 1$, $\textit{first}$ and $\textit{second}$ cannot be made equal with one edit, so return `false`; +- When $m = n$, $\textit{first}$ and $\textit{second}$ can be made equal with one edit only if there is exactly one different character; +- When $m - n = 1$, $\textit{first}$ and $\textit{second}$ can be made equal with one edit only if $\textit{second}$ is obtained by deleting one character from $\textit{first}$. We can use two pointers to achieve this. The time complexity is $O(n)$, where $n$ is the length of the string. The space complexity is $O(1)$. diff --git a/lcci/01.06.Compress String/README.md b/lcci/01.06.Compress String/README.md index 829eb7d532a86..2a08b263e8ae5 100644 --- a/lcci/01.06.Compress String/README.md +++ b/lcci/01.06.Compress String/README.md @@ -62,22 +62,6 @@ class Solution: return min(S, t, key=len) ``` -#### Python3 - -```python -class Solution: - def compressString(self, S: str) -> str: - t = [] - i, n = 0, len(S) - while i < n: - j = i + 1 - while j < n and S[j] == S[i]: - j += 1 - t.append(S[i] + str(j - i)) - i = j - return min(S, "".join(t), key=len) -``` - #### Java ```java diff --git a/lcci/01.06.Compress String/README_EN.md b/lcci/01.06.Compress String/README_EN.md index 10346e225a81c..e1a9f55e5b8a0 100644 --- a/lcci/01.06.Compress String/README_EN.md +++ b/lcci/01.06.Compress String/README_EN.md @@ -69,22 +69,6 @@ class Solution: return min(S, t, key=len) ``` -#### Python3 - -```python -class Solution: - def compressString(self, S: str) -> str: - t = [] - i, n = 0, len(S) - while i < n: - j = i + 1 - while j < n and S[j] == S[i]: - j += 1 - t.append(S[i] + str(j - i)) - i = j - return min(S, "".join(t), key=len) -``` - #### Java ```java diff --git a/lcci/01.06.Compress String/Solution2.py b/lcci/01.06.Compress String/Solution2.py deleted file mode 100644 index d3bc1c1aab18d..0000000000000 --- a/lcci/01.06.Compress String/Solution2.py +++ /dev/null @@ -1,11 +0,0 @@ -class Solution: - def compressString(self, S: str) -> str: - t = [] - i, n = 0, len(S) - while i < n: - j = i + 1 - while j < n and S[j] == S[i]: - j += 1 - t.append(S[i] + str(j - i)) - i = j - return min(S, "".join(t), key=len) diff --git a/lcci/01.07.Rotate Matrix/README.md b/lcci/01.07.Rotate Matrix/README.md index 2d6b196c90198..d9b2763c2a520 100644 --- a/lcci/01.07.Rotate Matrix/README.md +++ b/lcci/01.07.Rotate Matrix/README.md @@ -64,9 +64,9 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/01.07.Rotate%20Matrix ### 方法一:原地翻转 -根据题目要求,我们实际上需要将 $matrix[i][j]$ 旋转至 $matrix[j][n - i - 1]$。 +根据题目要求,我们实际上需要将 $\text{matrix}[i][j]$ 旋转至 $\text{matrix}[j][n - i - 1]$。 -我们可以先对矩阵进行上下翻转,即 $matrix[i][j]$ 和 $matrix[n - i - 1][j]$ 进行交换,然后再对矩阵进行主对角线翻转,即 $matrix[i][j]$ 和 $matrix[j][i]$ 进行交换。这样就能将 $matrix[i][j]$ 旋转至 $matrix[j][n - i - 1]$ 了。 +我们可以先对矩阵进行上下翻转,即 $\text{matrix}[i][j]$ 和 $\text{matrix}[n - i - 1][j]$ 进行交换,然后再对矩阵进行主对角线翻转,即 $\text{matrix}[i][j]$ 和 $\text{matrix}[j][i]$ 进行交换。这样就能将 $\text{matrix}[i][j]$ 旋转至 $\text{matrix}[j][n - i - 1]$ 了。 时间复杂度 $O(n^2)$,其中 $n$ 是矩阵的边长。空间复杂度 $O(1)$。 diff --git a/lcci/01.07.Rotate Matrix/README_EN.md b/lcci/01.07.Rotate Matrix/README_EN.md index f093f2a013175..8a1f0badd0a68 100644 --- a/lcci/01.07.Rotate Matrix/README_EN.md +++ b/lcci/01.07.Rotate Matrix/README_EN.md @@ -92,11 +92,11 @@ Rotate the matrix in place. It becomes: -### Solution 1: In-place Rotation +### Solution 1: In-Place Rotation -According to the problem requirements, we actually need to rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$. +According to the problem requirements, we need to rotate $\text{matrix}[i][j]$ to $\text{matrix}[j][n - i - 1]$. -We can first flip the matrix upside down, that is, swap $matrix[i][j]$ and $matrix[n - i - 1][j]$, and then flip the matrix along the main diagonal, that is, swap $matrix[i][j]$ and $matrix[j][i]$. This way, we can rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$. +We can first flip the matrix upside down, i.e., swap $\text{matrix}[i][j]$ with $\text{matrix}[n - i - 1][j]$, and then flip the matrix along the main diagonal, i.e., swap $\text{matrix}[i][j]$ with $\text{matrix}[j][i]$. This will rotate $\text{matrix}[i][j]$ to $\text{matrix}[j][n - i - 1]$. The time complexity is $O(n^2)$, where $n$ is the side length of the matrix. The space complexity is $O(1)$. diff --git a/lcci/02.08.Linked List Cycle/README.md b/lcci/02.08.Linked List Cycle/README.md index 37fbe9f8e76a7..facce4bf87406 100644 --- a/lcci/02.08.Linked List Cycle/README.md +++ b/lcci/02.08.Linked List Cycle/README.md @@ -44,6 +44,8 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/02.08.Linked%20List%2 +#### Python3 + ```python # Definition for singly-linked list. # class ListNode: @@ -66,6 +68,8 @@ class Solution: return ans ``` +#### Java + ```java /** * Definition for singly-linked list. @@ -98,6 +102,8 @@ public class Solution { } ``` +#### C++ + ```cpp /** * Definition for singly-linked list. @@ -129,6 +135,8 @@ public: }; ``` +#### Go + ```go /** * Definition for singly-linked list. @@ -155,6 +163,8 @@ func detectCycle(head *ListNode) *ListNode { } ``` +#### TypeScript + ```ts /** * Definition for singly-linked list. @@ -186,6 +196,8 @@ function detectCycle(head: ListNode | null): ListNode | null { } ``` +#### JavaScript + ```js /** * Definition for singly-linked list. @@ -217,6 +229,8 @@ var detectCycle = function (head) { }; ``` +#### Swift + ```swift /* * public class ListNode { @@ -251,4 +265,8 @@ class Solution { } ``` + + + + diff --git a/lcci/04.08.First Common Ancestor/README.md b/lcci/04.08.First Common Ancestor/README.md index d7a9fb878e8e4..c51706d069e79 100644 --- a/lcci/04.08.First Common Ancestor/README.md +++ b/lcci/04.08.First Common Ancestor/README.md @@ -22,7 +22,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/04.08.First%20Common% -### 方法一 +### 方法一:递归 + +我们首先判断根节点是否为空,或者根节点是否等于 $\textit{p}$ 或 $\textit{q}$,如果是的话,直接返回根节点。 + +然后递归地对左右子树进行查找,分别得到 $\textit{left}$ 和 $\textit{right}$。如果 $\textit{left}$ 和 $\textit{right}$ 都不为空,说明 $\textit{p}$ 和 $\textit{q}$ 分别在左右子树中,那么根节点就是最近公共祖先。否则,如果 $\textit{left}$ 和 $\textit{right}$ 中有一个为空,说明 $\textit{p}$ 和 $\textit{q}$ 都在非空的子树中,那么非空的子树的根节点就是最近公共祖先。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是二叉树中节点的数目。 @@ -41,11 +47,11 @@ class Solution: def lowestCommonAncestor( self, root: TreeNode, p: TreeNode, q: TreeNode ) -> TreeNode: - if root is None or root == p or root == q: + if root is None or root in [p, q]: return root left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) - return right if left is None else (left if right is None else root) + return root if left and right else left or right ``` #### Java @@ -72,6 +78,84 @@ class Solution { } ``` +#### C++ + +```cpp +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (!root || root == p || root == q) { + return root; + } + TreeNode* left = lowestCommonAncestor(root->left, p, q); + TreeNode* right = lowestCommonAncestor(root->right, p, q); + return left && right ? root : (left ? left : right); + } +}; +``` + +#### Go + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode { + if root == nil || root == p || root == q { + return root + } + left := lowestCommonAncestor(root.Left, p, q) + right := lowestCommonAncestor(root.Right, p, q) + if left == nil { + return right + } + if right == nil { + return left + } + return root +} +``` + +#### JavaScript + +```js +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function (root, p, q) { + if (!root || root === p || root === q) { + return root; + } + const left = lowestCommonAncestor(root.left, p, q); + const right = lowestCommonAncestor(root.right, p, q); + return left && right ? root : left || right; +}; +``` + #### Swift ```swift diff --git a/lcci/04.08.First Common Ancestor/README_EN.md b/lcci/04.08.First Common Ancestor/README_EN.md index 8df95cc286a11..e500060c3e04c 100644 --- a/lcci/04.08.First Common Ancestor/README_EN.md +++ b/lcci/04.08.First Common Ancestor/README_EN.md @@ -69,7 +69,13 @@ edit_url: https://github.com/doocs/leetcode/edit/main/lcci/04.08.First%20Common% -### Solution 1 +### Solution 1: Recursion + +First, we check if the root node is null or if the root node is equal to $\textit{p}$ or $\textit{q}$. If so, we return the root node directly. + +Then, we recursively search the left and right subtrees to get $\textit{left}$ and $\textit{right}$, respectively. If both $\textit{left}$ and $\textit{right}$ are not null, it means $\textit{p}$ and $\textit{q}$ are in the left and right subtrees, respectively, so the root node is the lowest common ancestor. Otherwise, if either $\textit{left}$ or $\textit{right}$ is null, it means both $\textit{p}$ and $\textit{q}$ are in the non-null subtree, so the root node of the non-null subtree is the lowest common ancestor. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary tree. @@ -88,11 +94,11 @@ class Solution: def lowestCommonAncestor( self, root: TreeNode, p: TreeNode, q: TreeNode ) -> TreeNode: - if root is None or root == p or root == q: + if root is None or root in [p, q]: return root left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) - return right if left is None else (left if right is None else root) + return root if left and right else left or right ``` #### Java @@ -119,6 +125,84 @@ class Solution { } ``` +#### C++ + +```cpp +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (!root || root == p || root == q) { + return root; + } + TreeNode* left = lowestCommonAncestor(root->left, p, q); + TreeNode* right = lowestCommonAncestor(root->right, p, q); + return left && right ? root : (left ? left : right); + } +}; +``` + +#### Go + +```go +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode { + if root == nil || root == p || root == q { + return root + } + left := lowestCommonAncestor(root.Left, p, q) + right := lowestCommonAncestor(root.Right, p, q) + if left == nil { + return right + } + if right == nil { + return left + } + return root +} +``` + +#### JavaScript + +```js +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function (root, p, q) { + if (!root || root === p || root === q) { + return root; + } + const left = lowestCommonAncestor(root.left, p, q); + const right = lowestCommonAncestor(root.right, p, q); + return left && right ? root : left || right; +}; +``` + #### Swift ```swift diff --git a/lcci/04.08.First Common Ancestor/Solution.cpp b/lcci/04.08.First Common Ancestor/Solution.cpp new file mode 100644 index 0000000000000..1cd5e13570f9b --- /dev/null +++ b/lcci/04.08.First Common Ancestor/Solution.cpp @@ -0,0 +1,20 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { + if (!root || root == p || root == q) { + return root; + } + TreeNode* left = lowestCommonAncestor(root->left, p, q); + TreeNode* right = lowestCommonAncestor(root->right, p, q); + return left && right ? root : (left ? left : right); + } +}; diff --git a/lcci/04.08.First Common Ancestor/Solution.go b/lcci/04.08.First Common Ancestor/Solution.go new file mode 100644 index 0000000000000..b2668e2c48820 --- /dev/null +++ b/lcci/04.08.First Common Ancestor/Solution.go @@ -0,0 +1,22 @@ +/** + * Definition for a binary tree node. + * type TreeNode struct { + * Val int + * Left *TreeNode + * Right *TreeNode + * } + */ +func lowestCommonAncestor(root *TreeNode, p *TreeNode, q *TreeNode) *TreeNode { + if root == nil || root == p || root == q { + return root + } + left := lowestCommonAncestor(root.Left, p, q) + right := lowestCommonAncestor(root.Right, p, q) + if left == nil { + return right + } + if right == nil { + return left + } + return root +} diff --git a/lcci/04.08.First Common Ancestor/Solution.js b/lcci/04.08.First Common Ancestor/Solution.js new file mode 100644 index 0000000000000..cba4ad1be11d1 --- /dev/null +++ b/lcci/04.08.First Common Ancestor/Solution.js @@ -0,0 +1,21 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function (root, p, q) { + if (!root || root === p || root === q) { + return root; + } + const left = lowestCommonAncestor(root.left, p, q); + const right = lowestCommonAncestor(root.right, p, q); + return left && right ? root : left || right; +}; diff --git a/lcci/04.08.First Common Ancestor/Solution.py b/lcci/04.08.First Common Ancestor/Solution.py index 1622fd413d1b0..ebd8bb7f1f46b 100644 --- a/lcci/04.08.First Common Ancestor/Solution.py +++ b/lcci/04.08.First Common Ancestor/Solution.py @@ -10,8 +10,8 @@ class Solution: def lowestCommonAncestor( self, root: TreeNode, p: TreeNode, q: TreeNode ) -> TreeNode: - if root is None or root == p or root == q: + if root is None or root in [p, q]: return root left = self.lowestCommonAncestor(root.left, p, q) right = self.lowestCommonAncestor(root.right, p, q) - return right if left is None else (left if right is None else root) + return root if left and right else left or right