From af4f7dfe7afa9158f458af3b3f87141db410e991 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 15 Jan 2025 14:05:43 +0800 Subject: [PATCH] feat: add solutions to lc problems: No.0965,0978 --- .../0965.Univalued Binary Tree/README.md | 80 ++++++++++++------- .../0965.Univalued Binary Tree/README_EN.md | 80 ++++++++++++------- .../0965.Univalued Binary Tree/Solution.cpp | 16 ++-- .../0965.Univalued Binary Tree/Solution.go | 9 ++- .../0965.Univalued Binary Tree/Solution.java | 11 ++- .../0965.Univalued Binary Tree/Solution.py | 9 ++- .../0965.Univalued Binary Tree/Solution.rs | 21 ++--- .../0965.Univalued Binary Tree/Solution.ts | 10 +-- .../0966.Vowel Spellchecker/README.md | 8 +- .../0966.Vowel Spellchecker/README_EN.md | 10 ++- .../0968.Binary Tree Cameras/README_EN.md | 24 +++++- .../README.md | 4 +- .../README_EN.md | 8 +- .../0978.Longest Turbulent Subarray/README.md | 28 ++++++- .../README_EN.md | 32 +++++++- .../Solution.rs | 17 ++++ 16 files changed, 259 insertions(+), 108 deletions(-) create mode 100644 solution/0900-0999/0978.Longest Turbulent Subarray/Solution.rs diff --git a/solution/0900-0999/0965.Univalued Binary Tree/README.md b/solution/0900-0999/0965.Univalued Binary Tree/README.md index 3c19bd0afd1b0..6058158e7e1b4 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/README.md +++ b/solution/0900-0999/0965.Univalued Binary Tree/README.md @@ -56,7 +56,15 @@ tags: -### 方法一 +### 方法一:DFS + +我们记根节点的值为 $x$,然后设计一个函数 $\text{dfs}(\text{root})$,它表示当前节点的值是否等于 $x$,并且它的左右子树也是单值二叉树。 + +在函数 $\text{dfs}(\text{root})$ 中,如果当前节点为空,那么返回 $\text{true}$,否则,如果当前节点的值等于 $x$,并且它的左右子树也是单值二叉树,那么返回 $\text{true}$,否则返回 $\text{false}$。 + +在主函数中,我们调用 $\text{dfs}(\text{root})$,并返回结果。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是树中的节点数目。 @@ -70,12 +78,13 @@ tags: # self.left = left # self.right = right class Solution: - def isUnivalTree(self, root: TreeNode) -> bool: - def dfs(node): - if node is None: + def isUnivalTree(self, root: Optional[TreeNode]) -> bool: + def dfs(root: Optional[TreeNode]) -> bool: + if root is None: return True - return node.val == root.val and dfs(node.left) and dfs(node.right) + return root.val == x and dfs(root.left) and dfs(root.right) + x = root.val return dfs(root) ``` @@ -98,15 +107,18 @@ class Solution: * } */ class Solution { + private int x; + public boolean isUnivalTree(TreeNode root) { - return dfs(root, root.val); + x = root.val; + return dfs(root); } - private boolean dfs(TreeNode root, int val) { + private boolean dfs(TreeNode root) { if (root == null) { return true; } - return root.val == val && dfs(root.left, val) && dfs(root.right, val); + return root.val == x && dfs(root.left) && dfs(root.right); } } ``` @@ -128,12 +140,14 @@ class Solution { class Solution { public: bool isUnivalTree(TreeNode* root) { - return dfs(root, root->val); - } - - bool dfs(TreeNode* root, int val) { - if (!root) return true; - return root->val == val && dfs(root->left, val) && dfs(root->right, val); + int x = root->val; + auto dfs = [&](this auto&& dfs, TreeNode* root) -> bool { + if (!root) { + return true; + } + return root->val == x && dfs(root->left) && dfs(root->right); + }; + return dfs(root); } }; ``` @@ -150,12 +164,13 @@ public: * } */ func isUnivalTree(root *TreeNode) bool { + x := root.Val var dfs func(*TreeNode) bool - dfs = func(node *TreeNode) bool { - if node == nil { + dfs = func(root *TreeNode) bool { + if root == nil { return true } - return node.Val == root.Val && dfs(node.Left) && dfs(node.Right) + return root.Val == x && dfs(root.Left) && dfs(root.Right) } return dfs(root) } @@ -179,14 +194,14 @@ func isUnivalTree(root *TreeNode) bool { */ function isUnivalTree(root: TreeNode | null): boolean { - const val = root.val; - const dfs = (root: TreeNode | null) => { - if (root == null) { + const x = root!.val; + const dfs = (root: TreeNode | null): boolean => { + if (!root) { return true; } - return root.val === val && dfs(root.left) && dfs(root.right); + return root.val === x && dfs(root.left) && dfs(root.right); }; - return dfs(root.left) && dfs(root.right); + return dfs(root); } ``` @@ -214,16 +229,19 @@ function isUnivalTree(root: TreeNode | null): boolean { use std::cell::RefCell; use std::rc::Rc; impl Solution { - fn dfs(val: i32, root: &Option>>) -> bool { - if root.is_none() { - return true; - } - let root = root.as_ref().unwrap().borrow(); - root.val == val && Self::dfs(val, &root.left) && Self::dfs(val, &root.right) - } pub fn is_unival_tree(root: Option>>) -> bool { - let root = root.as_ref().unwrap().borrow(); - Self::dfs(root.val, &root.left) && Self::dfs(root.val, &root.right) + let x = root.as_ref().unwrap().borrow().val; + + fn dfs(node: Option>>, x: i32) -> bool { + if let Some(n) = node { + let n = n.borrow(); + n.val == x && dfs(n.left.clone(), x) && dfs(n.right.clone(), x) + } else { + true + } + } + + dfs(root, x) } } ``` diff --git a/solution/0900-0999/0965.Univalued Binary Tree/README_EN.md b/solution/0900-0999/0965.Univalued Binary Tree/README_EN.md index ac899728e38d9..7707a0ab5e91d 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/README_EN.md +++ b/solution/0900-0999/0965.Univalued Binary Tree/README_EN.md @@ -52,7 +52,15 @@ tags: -### Solution 1 +### Solution 1: DFS + +We denote the value of the root node as $x$, and then design a function $\text{dfs}(\text{root})$, which indicates whether the current node's value is equal to $x$ and its left and right subtrees are also univalued binary trees. + +In the function $\text{dfs}(\text{root})$, if the current node is null, return $\text{true}$; otherwise, if the current node's value is equal to $x$ and its left and right subtrees are also univalued binary trees, return $\text{true}$; otherwise, return $\text{false}$. + +In the main function, we call $\text{dfs}(\text{root})$ and return the result. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the tree. @@ -66,12 +74,13 @@ tags: # self.left = left # self.right = right class Solution: - def isUnivalTree(self, root: TreeNode) -> bool: - def dfs(node): - if node is None: + def isUnivalTree(self, root: Optional[TreeNode]) -> bool: + def dfs(root: Optional[TreeNode]) -> bool: + if root is None: return True - return node.val == root.val and dfs(node.left) and dfs(node.right) + return root.val == x and dfs(root.left) and dfs(root.right) + x = root.val return dfs(root) ``` @@ -94,15 +103,18 @@ class Solution: * } */ class Solution { + private int x; + public boolean isUnivalTree(TreeNode root) { - return dfs(root, root.val); + x = root.val; + return dfs(root); } - private boolean dfs(TreeNode root, int val) { + private boolean dfs(TreeNode root) { if (root == null) { return true; } - return root.val == val && dfs(root.left, val) && dfs(root.right, val); + return root.val == x && dfs(root.left) && dfs(root.right); } } ``` @@ -124,12 +136,14 @@ class Solution { class Solution { public: bool isUnivalTree(TreeNode* root) { - return dfs(root, root->val); - } - - bool dfs(TreeNode* root, int val) { - if (!root) return true; - return root->val == val && dfs(root->left, val) && dfs(root->right, val); + int x = root->val; + auto dfs = [&](this auto&& dfs, TreeNode* root) -> bool { + if (!root) { + return true; + } + return root->val == x && dfs(root->left) && dfs(root->right); + }; + return dfs(root); } }; ``` @@ -146,12 +160,13 @@ public: * } */ func isUnivalTree(root *TreeNode) bool { + x := root.Val var dfs func(*TreeNode) bool - dfs = func(node *TreeNode) bool { - if node == nil { + dfs = func(root *TreeNode) bool { + if root == nil { return true } - return node.Val == root.Val && dfs(node.Left) && dfs(node.Right) + return root.Val == x && dfs(root.Left) && dfs(root.Right) } return dfs(root) } @@ -175,14 +190,14 @@ func isUnivalTree(root *TreeNode) bool { */ function isUnivalTree(root: TreeNode | null): boolean { - const val = root.val; - const dfs = (root: TreeNode | null) => { - if (root == null) { + const x = root!.val; + const dfs = (root: TreeNode | null): boolean => { + if (!root) { return true; } - return root.val === val && dfs(root.left) && dfs(root.right); + return root.val === x && dfs(root.left) && dfs(root.right); }; - return dfs(root.left) && dfs(root.right); + return dfs(root); } ``` @@ -210,16 +225,19 @@ function isUnivalTree(root: TreeNode | null): boolean { use std::cell::RefCell; use std::rc::Rc; impl Solution { - fn dfs(val: i32, root: &Option>>) -> bool { - if root.is_none() { - return true; - } - let root = root.as_ref().unwrap().borrow(); - root.val == val && Self::dfs(val, &root.left) && Self::dfs(val, &root.right) - } pub fn is_unival_tree(root: Option>>) -> bool { - let root = root.as_ref().unwrap().borrow(); - Self::dfs(root.val, &root.left) && Self::dfs(root.val, &root.right) + let x = root.as_ref().unwrap().borrow().val; + + fn dfs(node: Option>>, x: i32) -> bool { + if let Some(n) = node { + let n = n.borrow(); + n.val == x && dfs(n.left.clone(), x) && dfs(n.right.clone(), x) + } else { + true + } + } + + dfs(root, x) } } ``` diff --git a/solution/0900-0999/0965.Univalued Binary Tree/Solution.cpp b/solution/0900-0999/0965.Univalued Binary Tree/Solution.cpp index 472b182e6a984..972f4564e14b9 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/Solution.cpp +++ b/solution/0900-0999/0965.Univalued Binary Tree/Solution.cpp @@ -12,11 +12,13 @@ class Solution { public: bool isUnivalTree(TreeNode* root) { - return dfs(root, root->val); + int x = root->val; + auto dfs = [&](this auto&& dfs, TreeNode* root) -> bool { + if (!root) { + return true; + } + return root->val == x && dfs(root->left) && dfs(root->right); + }; + return dfs(root); } - - bool dfs(TreeNode* root, int val) { - if (!root) return true; - return root->val == val && dfs(root->left, val) && dfs(root->right, val); - } -}; \ No newline at end of file +}; diff --git a/solution/0900-0999/0965.Univalued Binary Tree/Solution.go b/solution/0900-0999/0965.Univalued Binary Tree/Solution.go index 570c9f7c7025d..99ba92d4bd933 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/Solution.go +++ b/solution/0900-0999/0965.Univalued Binary Tree/Solution.go @@ -7,12 +7,13 @@ * } */ func isUnivalTree(root *TreeNode) bool { + x := root.Val var dfs func(*TreeNode) bool - dfs = func(node *TreeNode) bool { - if node == nil { + dfs = func(root *TreeNode) bool { + if root == nil { return true } - return node.Val == root.Val && dfs(node.Left) && dfs(node.Right) + return root.Val == x && dfs(root.Left) && dfs(root.Right) } return dfs(root) -} \ No newline at end of file +} diff --git a/solution/0900-0999/0965.Univalued Binary Tree/Solution.java b/solution/0900-0999/0965.Univalued Binary Tree/Solution.java index 3c0959a3d389b..06d5128ad3e74 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/Solution.java +++ b/solution/0900-0999/0965.Univalued Binary Tree/Solution.java @@ -14,14 +14,17 @@ * } */ class Solution { + private int x; + public boolean isUnivalTree(TreeNode root) { - return dfs(root, root.val); + x = root.val; + return dfs(root); } - private boolean dfs(TreeNode root, int val) { + private boolean dfs(TreeNode root) { if (root == null) { return true; } - return root.val == val && dfs(root.left, val) && dfs(root.right, val); + return root.val == x && dfs(root.left) && dfs(root.right); } -} \ No newline at end of file +} diff --git a/solution/0900-0999/0965.Univalued Binary Tree/Solution.py b/solution/0900-0999/0965.Univalued Binary Tree/Solution.py index cfb87bbd2d79b..81350de53e9f3 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/Solution.py +++ b/solution/0900-0999/0965.Univalued Binary Tree/Solution.py @@ -5,10 +5,11 @@ # self.left = left # self.right = right class Solution: - def isUnivalTree(self, root: TreeNode) -> bool: - def dfs(node): - if node is None: + def isUnivalTree(self, root: Optional[TreeNode]) -> bool: + def dfs(root: Optional[TreeNode]) -> bool: + if root is None: return True - return node.val == root.val and dfs(node.left) and dfs(node.right) + return root.val == x and dfs(root.left) and dfs(root.right) + x = root.val return dfs(root) diff --git a/solution/0900-0999/0965.Univalued Binary Tree/Solution.rs b/solution/0900-0999/0965.Univalued Binary Tree/Solution.rs index 0cd077656d7ad..c5d20df5b76cf 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/Solution.rs +++ b/solution/0900-0999/0965.Univalued Binary Tree/Solution.rs @@ -19,15 +19,18 @@ use std::cell::RefCell; use std::rc::Rc; impl Solution { - fn dfs(val: i32, root: &Option>>) -> bool { - if root.is_none() { - return true; - } - let root = root.as_ref().unwrap().borrow(); - root.val == val && Self::dfs(val, &root.left) && Self::dfs(val, &root.right) - } pub fn is_unival_tree(root: Option>>) -> bool { - let root = root.as_ref().unwrap().borrow(); - Self::dfs(root.val, &root.left) && Self::dfs(root.val, &root.right) + let x = root.as_ref().unwrap().borrow().val; + + fn dfs(node: Option>>, x: i32) -> bool { + if let Some(n) = node { + let n = n.borrow(); + n.val == x && dfs(n.left.clone(), x) && dfs(n.right.clone(), x) + } else { + true + } + } + + dfs(root, x) } } diff --git a/solution/0900-0999/0965.Univalued Binary Tree/Solution.ts b/solution/0900-0999/0965.Univalued Binary Tree/Solution.ts index 367c40847290d..9af60e33c6b2a 100644 --- a/solution/0900-0999/0965.Univalued Binary Tree/Solution.ts +++ b/solution/0900-0999/0965.Univalued Binary Tree/Solution.ts @@ -13,12 +13,12 @@ */ function isUnivalTree(root: TreeNode | null): boolean { - const val = root.val; - const dfs = (root: TreeNode | null) => { - if (root == null) { + const x = root!.val; + const dfs = (root: TreeNode | null): boolean => { + if (!root) { return true; } - return root.val === val && dfs(root.left) && dfs(root.right); + return root.val === x && dfs(root.left) && dfs(root.right); }; - return dfs(root.left) && dfs(root.right); + return dfs(root); } diff --git a/solution/0900-0999/0966.Vowel Spellchecker/README.md b/solution/0900-0999/0966.Vowel Spellchecker/README.md index 723a5becb441d..5e8bbf32889bf 100644 --- a/solution/0900-0999/0966.Vowel Spellchecker/README.md +++ b/solution/0900-0999/0966.Vowel Spellchecker/README.md @@ -85,13 +85,13 @@ tags: ### 方法一:哈希表 -遍历 `wordlist`,将单词按照大小写不敏感、元音不敏感的规则分别存入哈希表 `low` 和 `pat` 中,其中 `low` 的键为单词的小写形式,`pat` 的键为将单词的元音字母替换为 `*` 后的字符串,值为单词本身。用哈希表 `s` 存储 `wordlist` 中的单词。 +我们遍历 $\textit{wordlist}$,将单词按照大小写不敏感、元音不敏感的规则分别存入哈希表 $\textit{low}$ 和 $\textit{pat}$ 中,其中 $\textit{low}$ 的键为单词的小写形式,$\textit{pat}$ 的键为将单词的元音字母替换为 `*` 后的字符串,值为单词本身。用哈希表 $\textit{s}$ 存储 $\textit{wordlist}$ 中的单词。 -遍历 `queries`,对于每个单词 `q`,如果 `q` 在 `s` 中,说明 `q` 在 `wordlist` 中,直接将 `q` 加入答案数组 `ans` 中;否则,如果 `q` 的小写形式在 `low` 中,说明 `q` 在 `wordlist` 中,且大小写不敏感,将 `low[q.lower()]` 加入答案数组 `ans` 中;否则,如果将 `q` 的元音字母替换为 `*` 后的字符串在 `pat` 中,说明 `q` 在 `wordlist` 中,且元音不敏感,将 `pat[f(q)]` 加入答案数组 `ans` 中;否则,说明 `q` 在 `wordlist` 中,且大小写和元音都不敏感,将空字符串加入答案数组 `ans` 中。 +遍历 $\textit{queries}$,对于每个单词 $\textit{q}$,如果 $\textit{q}$ 在 $\textit{s}$ 中,说明 $\textit{q}$ 在 $\textit{wordlist}$ 中,直接将 $\textit{q}$ 加入答案数组 $\textit{ans}$ 中;否则,如果 $\textit{q}$ 的小写形式在 $\textit{low}$ 中,说明 $\textit{q}$ 在 $\textit{wordlist}$ 中,且大小写不敏感,将 $\textit{low}[q.\text{lower}()]$ 加入答案数组 $\textit{ans}$ 中;否则,如果将 $\textit{q}$ 的元音字母替换为 `*` 后的字符串在 $\textit{pat}$ 中,说明 $\textit{q}$ 在 $\textit{wordlist}$ 中,且元音不敏感,将 $\textit{pat}[f(q)]$ 加入答案数组 $\textit{ans}$ 中;否则,说明 $\textit{q}$ 在 $\textit{wordlist}$ 中,且大小写和元音都不敏感,将空字符串加入答案数组 $\textit{ans}$ 中。 -最后返回答案数组 `ans` 即可。 +最后返回答案数组 $\textit{ans}$ 即可。 -时间复杂度 $O(n+m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为 `wordlist` 和 `queries` 的长度。 +时间复杂度 $O(n + m)$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为 $\textit{wordlist}$ 和 $\textit{queries}$ 的长度。 diff --git a/solution/0900-0999/0966.Vowel Spellchecker/README_EN.md b/solution/0900-0999/0966.Vowel Spellchecker/README_EN.md index 5987839c4b1b8..49c4ba73b8b30 100644 --- a/solution/0900-0999/0966.Vowel Spellchecker/README_EN.md +++ b/solution/0900-0999/0966.Vowel Spellchecker/README_EN.md @@ -75,7 +75,15 @@ tags: -### Solution 1 +### Solution 1: Hash Table + +We traverse the $\textit{wordlist}$ and store the words in hash tables $\textit{low}$ and $\textit{pat}$ according to case-insensitive and vowel-insensitive rules, respectively. The key of $\textit{low}$ is the lowercase form of the word, and the key of $\textit{pat}$ is the string obtained by replacing the vowels of the word with `*`, with the value being the word itself. We use the hash table $\textit{s}$ to store the words in $\textit{wordlist}$. + +We traverse $\textit{queries}$, for each word $\textit{q}$, if $\textit{q}$ is in $\textit{s}$, it means $\textit{q}$ is in $\textit{wordlist}$, and we directly add $\textit{q}$ to the answer array $\textit{ans}$; otherwise, if the lowercase form of $\textit{q}$ is in $\textit{low}$, it means $\textit{q}$ is in $\textit{wordlist}$ and is case-insensitive, and we add $\textit{low}[q.\text{lower}()]$ to the answer array $\textit{ans}$; otherwise, if the string obtained by replacing the vowels of $\textit{q}$ with `*` is in $\textit{pat}$, it means $\textit{q}$ is in $\textit{wordlist}$ and is vowel-insensitive, and we add $\textit{pat}[f(q)]$ to the answer array $\textit{ans}$; otherwise, it means $\textit{q}$ is not in $\textit{wordlist}$, and we add an empty string to the answer array $\textit{ans}$. + +Finally, we return the answer array $\textit{ans}$. + +The time complexity is $O(n + m)$, and the space complexity is $O(n)$, where $n$ and $m$ are the lengths of $\textit{wordlist}$ and $\textit{queries}$, respectively. diff --git a/solution/0900-0999/0968.Binary Tree Cameras/README_EN.md b/solution/0900-0999/0968.Binary Tree Cameras/README_EN.md index 95ddedb8a74a5..b097f6146ba21 100644 --- a/solution/0900-0999/0968.Binary Tree Cameras/README_EN.md +++ b/solution/0900-0999/0968.Binary Tree Cameras/README_EN.md @@ -54,7 +54,29 @@ tags: -### Solution 1 +### Solution 1: Dynamic Programming (Tree DP) + +For each node, we define three states: + +- `a`: The current node has a camera +- `b`: The current node does not have a camera, but is monitored by its children +- `c`: The current node does not have a camera and is not monitored by its children + +Next, we design a function $dfs(root)$, which will return an array of length 3, representing the minimum number of cameras in the subtree rooted at `root` for the three states. The answer is $\min(dfs(root)[0], dfs(root)[1])$. + +The calculation process of the function $dfs(root)$ is as follows: + +If `root` is null, return $[inf, 0, 0]$, where `inf` represents a very large number, used to indicate an impossible situation. + +Otherwise, we recursively calculate the left and right subtrees of `root`, obtaining $[la, lb, lc]$ and $[ra, rb, rc]$ respectively. + +- If the current node has a camera, then its left and right children must be in a monitored state, i.e., $a = \min(la, lb, lc) + \min(ra, rb, rc) + 1$. +- If the current node does not have a camera but is monitored by its children, then one or both of the children must have a camera, i.e., $b = \min(la + rb, lb + ra, la + ra)$. +- If the current node does not have a camera and is not monitored by its children, then the children must be monitored by their children, i.e., $c = lb + rb$. + +Finally, we return $[a, b, c]$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the binary tree. diff --git a/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README.md b/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README.md index 04038c4aec64e..b6029b5e002af 100644 --- a/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README.md +++ b/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README.md @@ -74,9 +74,9 @@ tags: ### 方法一:DFS -我们可以通过深度优先搜索的方式遍历整棵树,用一个下标 $i$ 记录当前遍历到的节点在数组 $voyage$ 中的下标,如果当前遍历到的节点的值不等于 $voyage[i]$,那么说明翻转后无法匹配,我们标记 $ok$ 为 `false`,并直接返回。否则,我们将 $i$ 的值加 $1$,然后判断当前节点是否有左子节点,如果没有,或者左子节点的值等于 $voyage[i]$,那么我们递归遍历当前的左右子节点;否则,我们需要翻转当前节点,然后再递归遍历当前的右子节点和左子节点。 +我们可以通过深度优先搜索的方式遍历整棵树,用一个下标 $i$ 记录当前遍历到的节点在数组 $\textit{voyage}$ 中的下标,如果当前遍历到的节点的值不等于 $\textit{voyage}[i]$,那么说明翻转后无法匹配,我们标记 $\textit{ok}$ 为 `false`,并直接返回。否则,我们将 $i$ 的值加 $1$,然后判断当前节点是否有左子节点,如果没有,或者左子节点的值等于 $\textit{voyage}[i]$,那么我们递归遍历当前的左右子节点;否则,我们需要翻转当前节点,然后再递归遍历当前的右子节点和左子节点。 -搜索结束后,如果 $ok$ 为 `true`,那么说明翻转后可以匹配,我们返回答案数组 $ans$,否则返回 $[-1]$。 +搜索结束后,如果 $\textit{ok}$ 为 `true`,那么说明翻转后可以匹配,我们返回答案数组 $\textit{ans}$,否则返回 $[-1]$。 时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是树中的节点数目。 diff --git a/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README_EN.md b/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README_EN.md index 8df6528ec2fdd..38b04f0ef3b18 100644 --- a/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README_EN.md +++ b/solution/0900-0999/0971.Flip Binary Tree To Match Preorder Traversal/README_EN.md @@ -68,7 +68,13 @@ tags: -### Solution 1 +### Solution 1: DFS + +We can traverse the entire tree using depth-first search, using an index $i$ to record the current node's index in the $\textit{voyage}$ array. If the value of the current node does not equal $\textit{voyage}[i]$, it means that it is impossible to match after flipping, we mark $\textit{ok}$ as `false` and return immediately. Otherwise, we increment $i$ by $1$, then check if the current node has a left child. If it does not, or if the value of the left child equals $\textit{voyage}[i]$, we recursively traverse the current left and right children; otherwise, we need to flip the current node and then recursively traverse the current right and left children. + +After the search, if $\textit{ok}$ is `true`, it means that it is possible to match after flipping, and we return the answer array $\textit{ans}$, otherwise, we return $[-1]$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the number of nodes in the tree. diff --git a/solution/0900-0999/0978.Longest Turbulent Subarray/README.md b/solution/0900-0999/0978.Longest Turbulent Subarray/README.md index fffb50a605d1e..6d9e02410045a 100644 --- a/solution/0900-0999/0978.Longest Turbulent Subarray/README.md +++ b/solution/0900-0999/0978.Longest Turbulent Subarray/README.md @@ -81,13 +81,13 @@ tags: ### 方法一:动态规划 -我们定义 $f[i]$ 表示以 $nums[i]$ 结尾且结尾处于上升状态的最长湍流子数组的长度,定义 $g[i]$ 表示以 $nums[i]$ 结尾且结尾处于下降状态的最长湍流子数组的长度。初始时 $f[0] = 1$, $g[0] = 1$。答案为 $max(f[i], g[i])$。 +我们定义 $f[i]$ 表示以 $\textit{nums}[i]$ 结尾且结尾处于上升状态的最长湍流子数组的长度,定义 $g[i]$ 表示以 $\textit{nums}[i]$ 结尾且结尾处于下降状态的最长湍流子数组的长度。初始时 $f[0] = 1$, $g[0] = 1$。答案为 $\max(f[i], g[i])$。 -对于 $i \gt 0$,若 $nums[i] \gt nums[i - 1]$,则 $f[i] = g[i - 1] + 1$,否则 $f[i] = 1$;若 $nums[i] \lt nums[i - 1]$,则 $g[i] = f[i - 1] + 1$,否则 $g[i] = 1$。 +对于 $i \gt 0$,若 $\textit{nums}[i] \gt \textit{nums}[i - 1]$,则 $f[i] = g[i - 1] + 1$,否则 $f[i] = 1$;若 $\textit{nums}[i] \lt \textit{nums}[i - 1]$,则 $g[i] = f[i - 1] + 1$,否则 $g[i] = 1$。 由于 $f[i]$ 和 $g[i]$ 只与 $f[i - 1]$ 和 $g[i - 1]$ 有关,因此可以使用两个变量代替数组。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。 +时间复杂度 $O(n)$,其中 $n$ 为数组长度。空间复杂度 $O(1)$。 @@ -180,6 +180,28 @@ function maxTurbulenceSize(arr: number[]): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn max_turbulence_size(arr: Vec) -> i32 { + let mut ans = 1; + let mut f = 1; + let mut g = 1; + + for i in 1..arr.len() { + let ff = if arr[i - 1] < arr[i] { g + 1 } else { 1 }; + let gg = if arr[i - 1] > arr[i] { f + 1 } else { 1 }; + f = ff; + g = gg; + ans = ans.max(f.max(g)); + } + + ans + } +} +``` + diff --git a/solution/0900-0999/0978.Longest Turbulent Subarray/README_EN.md b/solution/0900-0999/0978.Longest Turbulent Subarray/README_EN.md index b07a973fa9ef3..741a9e7b12fee 100644 --- a/solution/0900-0999/0978.Longest Turbulent Subarray/README_EN.md +++ b/solution/0900-0999/0978.Longest Turbulent Subarray/README_EN.md @@ -78,7 +78,15 @@ tags: -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i]$ as the length of the longest turbulent subarray ending at $\textit{nums}[i]$ with an increasing state, and $g[i]$ as the length of the longest turbulent subarray ending at $\textit{nums}[i]$ with a decreasing state. Initially, $f[0] = 1$, $g[0] = 1$. The answer is $\max(f[i], g[i])$. + +For $i \gt 0$, if $\textit{nums}[i] \gt \textit{nums}[i - 1]$, then $f[i] = g[i - 1] + 1$, otherwise $f[i] = 1$; if $\textit{nums}[i] \lt \textit{nums}[i - 1]$, then $g[i] = f[i - 1] + 1$, otherwise $g[i] = 1$. + +Since $f[i]$ and $g[i]$ are only related to $f[i - 1]$ and $g[i - 1]$, two variables can be used instead of arrays. + +The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$. @@ -171,6 +179,28 @@ function maxTurbulenceSize(arr: number[]): number { } ``` +#### Rust + +```rust +impl Solution { + pub fn max_turbulence_size(arr: Vec) -> i32 { + let mut ans = 1; + let mut f = 1; + let mut g = 1; + + for i in 1..arr.len() { + let ff = if arr[i - 1] < arr[i] { g + 1 } else { 1 }; + let gg = if arr[i - 1] > arr[i] { f + 1 } else { 1 }; + f = ff; + g = gg; + ans = ans.max(f.max(g)); + } + + ans + } +} +``` + diff --git a/solution/0900-0999/0978.Longest Turbulent Subarray/Solution.rs b/solution/0900-0999/0978.Longest Turbulent Subarray/Solution.rs new file mode 100644 index 0000000000000..6531bdd4fd9d5 --- /dev/null +++ b/solution/0900-0999/0978.Longest Turbulent Subarray/Solution.rs @@ -0,0 +1,17 @@ +impl Solution { + pub fn max_turbulence_size(arr: Vec) -> i32 { + let mut ans = 1; + let mut f = 1; + let mut g = 1; + + for i in 1..arr.len() { + let ff = if arr[i - 1] < arr[i] { g + 1 } else { 1 }; + let gg = if arr[i - 1] > arr[i] { f + 1 } else { 1 }; + f = ff; + g = gg; + ans = ans.max(f.max(g)); + } + + ans + } +}