From 37677f926ddb1d567e2bc033cbf37649647a9d85 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 16 Dec 2023 17:42:41 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problems: No.0896~0898 * No.0896.Monotonic Array * No.0897.Increasing Order Search Tree * No.0898.Bitwise ORs of Subarray --- .../0800-0899/0896.Monotonic Array/README.md | 113 +++++++---------- .../0896.Monotonic Array/README_EN.md | 119 ++++++++---------- .../0896.Monotonic Array/Solution.cpp | 14 ++- .../0896.Monotonic Array/Solution.go | 14 +-- .../0896.Monotonic Array/Solution.java | 12 +- .../0896.Monotonic Array/Solution.js | 14 +-- .../0896.Monotonic Array/Solution.py | 6 +- .../0896.Monotonic Array/Solution.rs | 19 ++- .../0896.Monotonic Array/Solution.ts | 18 ++- .../README.md | 71 ++++++++--- .../README_EN.md | 71 ++++++++--- .../Solution.cpp | 23 ++-- .../Solution.py | 3 +- .../Solution.ts | 30 +++++ .../0898.Bitwise ORs of Subarrays/README.md | 114 ++++++++++------- .../README_EN.md | 115 ++++++++++------- .../Solution.cpp | 31 +++-- .../0898.Bitwise ORs of Subarrays/Solution.go | 23 ++-- .../Solution.java | 33 +++-- .../0898.Bitwise ORs of Subarrays/Solution.py | 21 ++-- .../0898.Bitwise ORs of Subarrays/Solution.ts | 17 +++ 21 files changed, 506 insertions(+), 375 deletions(-) create mode 100644 solution/0800-0899/0897.Increasing Order Search Tree/Solution.ts create mode 100644 solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.ts diff --git a/solution/0800-0899/0896.Monotonic Array/README.md b/solution/0800-0899/0896.Monotonic Array/README.md index d1e8dba37e59d..3fdbed747b453 100644 --- a/solution/0800-0899/0896.Monotonic Array/README.md +++ b/solution/0800-0899/0896.Monotonic Array/README.md @@ -57,7 +57,7 @@ 否则遍历结束,说明是单调数组,返回 `true`。 -时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组长度。 +时间复杂度 $O(n)$,其中 $n$ 为数组长度。空间复杂度 $O(1)$。 @@ -68,23 +68,9 @@ ```python class Solution: def isMonotonic(self, nums: List[int]) -> bool: - isIncr = isDecr = False - for i, v in enumerate(nums[1:]): - if v < nums[i]: - isIncr = True - elif v > nums[i]: - isDecr = True - if isIncr and isDecr: - return False - return True -``` - -```python -class Solution: - def isMonotonic(self, nums: List[int]) -> bool: - incr = all(a <= b for a, b in pairwise(nums)) - decr = all(a >= b for a, b in pairwise(nums)) - return incr or decr + asc = all(a <= b for a, b in pairwise(nums)) + desc = all(a >= b for a, b in pairwise(nums)) + return asc or desc ``` ### **Java** @@ -94,14 +80,14 @@ class Solution: ```java class Solution { public boolean isMonotonic(int[] nums) { - boolean isIncr = false, isDecr = false; + boolean asc = false, desc = false; for (int i = 1; i < nums.length; ++i) { - if (nums[i] < nums[i - 1]) { - isIncr = true; - } else if (nums[i] > nums[i - 1]) { - isDecr = true; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isIncr && isDecr) { + if (asc && desc) { return false; } } @@ -116,12 +102,16 @@ class Solution { class Solution { public: bool isMonotonic(vector& nums) { - bool isIncr = false; - bool isDecr = false; + bool asc = false, desc = false; for (int i = 1; i < nums.size(); ++i) { - if (nums[i] < nums[i - 1]) isIncr = true; - if (nums[i] > nums[i - 1]) isDecr = true; - if (isIncr && isDecr) return false; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; + } + if (asc && desc) { + return false; + } } return true; } @@ -132,14 +122,14 @@ public: ```go func isMonotonic(nums []int) bool { - isIncr, isDecr := false, false - for i, v := range nums[1:] { - if v < nums[i] { - isIncr = true - } else if v > nums[i] { - isDecr = true + asc, desc := false, false + for i, x := range nums[1:] { + if nums[i] < x { + asc = true + } else if nums[i] > x { + desc = true } - if isIncr && isDecr { + if asc && desc { return false } } @@ -155,16 +145,14 @@ func isMonotonic(nums []int) bool { * @return {boolean} */ var isMonotonic = function (nums) { - let isIncr = false; - let isDecr = false; + let [asc, desc] = [false, false]; for (let i = 1; i < nums.length; ++i) { - if (nums[i] < nums[i - 1]) { - isIncr = true; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (nums[i] > nums[i - 1]) { - isDecr = true; - } - if (isIncr && isDecr) { + if (asc && desc) { return false; } } @@ -176,18 +164,14 @@ var isMonotonic = function (nums) { ```ts function isMonotonic(nums: number[]): boolean { - const n = nums.length; - let isOrder = false; - let isDecs = false; - for (let i = 1; i < n; i++) { - const pre = nums[i - 1]; - const cur = nums[i]; - if (pre < cur) { - isOrder = true; - } else if (pre > cur) { - isDecs = true; + let [asc, desc] = [false, false]; + for (let i = 1; i < nums.length; ++i) { + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isOrder && isDecs) { + if (asc && desc) { return false; } } @@ -200,18 +184,15 @@ function isMonotonic(nums: number[]): boolean { ```rust impl Solution { pub fn is_monotonic(nums: Vec) -> bool { - let n = nums.len(); - let mut is_order = false; - let mut is_decs = false; - for i in 1..n { - let pre = nums[i - 1]; - let cur = nums[i]; - if pre < cur { - is_order = true; - } else if pre > cur { - is_decs = true; + let mut asc = false; + let mut desc = false; + for i in 1..nums.len() { + if nums[i - 1] < nums[i] { + asc = true; + } else if nums[i - 1] > nums[i] { + desc = true; } - if is_order && is_decs { + if asc && desc { return false; } } diff --git a/solution/0800-0899/0896.Monotonic Array/README_EN.md b/solution/0800-0899/0896.Monotonic Array/README_EN.md index 3b16aa507c583..b7deeb93cca1b 100644 --- a/solution/0800-0899/0896.Monotonic Array/README_EN.md +++ b/solution/0800-0899/0896.Monotonic Array/README_EN.md @@ -42,6 +42,14 @@ ## Solutions +**Solution 1: Single Traversal** + +We traverse the array, and if an increasing or decreasing situation occurs, we record it. We then check whether both increasing and decreasing situations have occurred. If both have occurred, it means that the array is not monotonic, and we return `false`. + +Otherwise, if we reach the end of the traversal, it means that the array is monotonic, and we return `true`. + +The time complexity is $O(n)$, where $n$ is the length of the array. The space complexity is $O(1)$. + ### **Python3** @@ -49,23 +57,9 @@ ```python class Solution: def isMonotonic(self, nums: List[int]) -> bool: - isIncr = isDecr = False - for i, v in enumerate(nums[1:]): - if v < nums[i]: - isIncr = True - elif v > nums[i]: - isDecr = True - if isIncr and isDecr: - return False - return True -``` - -```python -class Solution: - def isMonotonic(self, nums: List[int]) -> bool: - incr = all(a <= b for a, b in pairwise(nums)) - decr = all(a >= b for a, b in pairwise(nums)) - return incr or decr + asc = all(a <= b for a, b in pairwise(nums)) + desc = all(a >= b for a, b in pairwise(nums)) + return asc or desc ``` ### **Java** @@ -73,14 +67,14 @@ class Solution: ```java class Solution { public boolean isMonotonic(int[] nums) { - boolean isIncr = false, isDecr = false; + boolean asc = false, desc = false; for (int i = 1; i < nums.length; ++i) { - if (nums[i] < nums[i - 1]) { - isIncr = true; - } else if (nums[i] > nums[i - 1]) { - isDecr = true; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isIncr && isDecr) { + if (asc && desc) { return false; } } @@ -95,12 +89,16 @@ class Solution { class Solution { public: bool isMonotonic(vector& nums) { - bool isIncr = false; - bool isDecr = false; + bool asc = false, desc = false; for (int i = 1; i < nums.size(); ++i) { - if (nums[i] < nums[i - 1]) isIncr = true; - if (nums[i] > nums[i - 1]) isDecr = true; - if (isIncr && isDecr) return false; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; + } + if (asc && desc) { + return false; + } } return true; } @@ -111,14 +109,14 @@ public: ```go func isMonotonic(nums []int) bool { - isIncr, isDecr := false, false - for i, v := range nums[1:] { - if v < nums[i] { - isIncr = true - } else if v > nums[i] { - isDecr = true + asc, desc := false, false + for i, x := range nums[1:] { + if nums[i] < x { + asc = true + } else if nums[i] > x { + desc = true } - if isIncr && isDecr { + if asc && desc { return false } } @@ -134,16 +132,14 @@ func isMonotonic(nums []int) bool { * @return {boolean} */ var isMonotonic = function (nums) { - let isIncr = false; - let isDecr = false; + let [asc, desc] = [false, false]; for (let i = 1; i < nums.length; ++i) { - if (nums[i] < nums[i - 1]) { - isIncr = true; - } - if (nums[i] > nums[i - 1]) { - isDecr = true; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isIncr && isDecr) { + if (asc && desc) { return false; } } @@ -155,18 +151,14 @@ var isMonotonic = function (nums) { ```ts function isMonotonic(nums: number[]): boolean { - const n = nums.length; - let isOrder = false; - let isDecs = false; - for (let i = 1; i < n; i++) { - const pre = nums[i - 1]; - const cur = nums[i]; - if (pre < cur) { - isOrder = true; - } else if (pre > cur) { - isDecs = true; + let [asc, desc] = [false, false]; + for (let i = 1; i < nums.length; ++i) { + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isOrder && isDecs) { + if (asc && desc) { return false; } } @@ -179,18 +171,15 @@ function isMonotonic(nums: number[]): boolean { ```rust impl Solution { pub fn is_monotonic(nums: Vec) -> bool { - let n = nums.len(); - let mut is_order = false; - let mut is_decs = false; - for i in 1..n { - let pre = nums[i - 1]; - let cur = nums[i]; - if pre < cur { - is_order = true; - } else if pre > cur { - is_decs = true; + let mut asc = false; + let mut desc = false; + for i in 1..nums.len() { + if nums[i - 1] < nums[i] { + asc = true; + } else if nums[i - 1] > nums[i] { + desc = true; } - if is_order && is_decs { + if asc && desc { return false; } } diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.cpp b/solution/0800-0899/0896.Monotonic Array/Solution.cpp index a95d063c1a935..6145b84e605e5 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.cpp +++ b/solution/0800-0899/0896.Monotonic Array/Solution.cpp @@ -1,12 +1,16 @@ class Solution { public: bool isMonotonic(vector& nums) { - bool isIncr = false; - bool isDecr = false; + bool asc = false, desc = false; for (int i = 1; i < nums.size(); ++i) { - if (nums[i] < nums[i - 1]) isIncr = true; - if (nums[i] > nums[i - 1]) isDecr = true; - if (isIncr && isDecr) return false; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; + } + if (asc && desc) { + return false; + } } return true; } diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.go b/solution/0800-0899/0896.Monotonic Array/Solution.go index cdaa5b1b3c09c..beef58b7d4b62 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.go +++ b/solution/0800-0899/0896.Monotonic Array/Solution.go @@ -1,12 +1,12 @@ func isMonotonic(nums []int) bool { - isIncr, isDecr := false, false - for i, v := range nums[1:] { - if v < nums[i] { - isIncr = true - } else if v > nums[i] { - isDecr = true + asc, desc := false, false + for i, x := range nums[1:] { + if nums[i] < x { + asc = true + } else if nums[i] > x { + desc = true } - if isIncr && isDecr { + if asc && desc { return false } } diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.java b/solution/0800-0899/0896.Monotonic Array/Solution.java index 2c08033ec8b45..95c351ec0fa8a 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.java +++ b/solution/0800-0899/0896.Monotonic Array/Solution.java @@ -1,13 +1,13 @@ class Solution { public boolean isMonotonic(int[] nums) { - boolean isIncr = false, isDecr = false; + boolean asc = false, desc = false; for (int i = 1; i < nums.length; ++i) { - if (nums[i] < nums[i - 1]) { - isIncr = true; - } else if (nums[i] > nums[i - 1]) { - isDecr = true; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isIncr && isDecr) { + if (asc && desc) { return false; } } diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.js b/solution/0800-0899/0896.Monotonic Array/Solution.js index ee682b09211a0..5d066fe8bb823 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.js +++ b/solution/0800-0899/0896.Monotonic Array/Solution.js @@ -3,16 +3,14 @@ * @return {boolean} */ var isMonotonic = function (nums) { - let isIncr = false; - let isDecr = false; + let [asc, desc] = [false, false]; for (let i = 1; i < nums.length; ++i) { - if (nums[i] < nums[i - 1]) { - isIncr = true; + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (nums[i] > nums[i - 1]) { - isDecr = true; - } - if (isIncr && isDecr) { + if (asc && desc) { return false; } } diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.py b/solution/0800-0899/0896.Monotonic Array/Solution.py index 2a8314fe3b11b..a4b7d0f176786 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.py +++ b/solution/0800-0899/0896.Monotonic Array/Solution.py @@ -1,5 +1,5 @@ class Solution: def isMonotonic(self, nums: List[int]) -> bool: - incr = all(a <= b for a, b in pairwise(nums)) - decr = all(a >= b for a, b in pairwise(nums)) - return incr or decr + asc = all(a <= b for a, b in pairwise(nums)) + desc = all(a >= b for a, b in pairwise(nums)) + return asc or desc diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.rs b/solution/0800-0899/0896.Monotonic Array/Solution.rs index a4fded4d5684c..bab54284449b9 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.rs +++ b/solution/0800-0899/0896.Monotonic Array/Solution.rs @@ -1,17 +1,14 @@ impl Solution { pub fn is_monotonic(nums: Vec) -> bool { - let n = nums.len(); - let mut is_order = false; - let mut is_decs = false; - for i in 1..n { - let pre = nums[i - 1]; - let cur = nums[i]; - if pre < cur { - is_order = true; - } else if pre > cur { - is_decs = true; + let mut asc = false; + let mut desc = false; + for i in 1..nums.len() { + if nums[i - 1] < nums[i] { + asc = true; + } else if nums[i - 1] > nums[i] { + desc = true; } - if is_order && is_decs { + if asc && desc { return false; } } diff --git a/solution/0800-0899/0896.Monotonic Array/Solution.ts b/solution/0800-0899/0896.Monotonic Array/Solution.ts index 85ee7e360ba28..e73f829c0fdc7 100644 --- a/solution/0800-0899/0896.Monotonic Array/Solution.ts +++ b/solution/0800-0899/0896.Monotonic Array/Solution.ts @@ -1,16 +1,12 @@ function isMonotonic(nums: number[]): boolean { - const n = nums.length; - let isOrder = false; - let isDecs = false; - for (let i = 1; i < n; i++) { - const pre = nums[i - 1]; - const cur = nums[i]; - if (pre < cur) { - isOrder = true; - } else if (pre > cur) { - isDecs = true; + let [asc, desc] = [false, false]; + for (let i = 1; i < nums.length; ++i) { + if (nums[i - 1] < nums[i]) { + asc = true; + } else if (nums[i - 1] > nums[i]) { + desc = true; } - if (isOrder && isDecs) { + if (asc && desc) { return false; } } diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/README.md b/solution/0800-0899/0897.Increasing Order Search Tree/README.md index 8d8175043fb0b..a7d3fdbcdd2a6 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/README.md +++ b/solution/0800-0899/0897.Increasing Order Search Tree/README.md @@ -37,13 +37,15 @@ -**方法一:中序遍历** +**方法一:DFS 中序遍历** -中序遍历过程中改变指针指向。 +我们定义一个虚拟节点 $dummy$,初始时 $dummy$ 的右子节点指向根节点 $root$,定义一个指针 $prev$ 指向 $dummy$。 -时间复杂度 $O(n)$。 +我们对二叉搜索树进行中序遍历,遍历过程中,每遍历到一个节点,就将 $prev$ 的右子节点指向它,然后将当前节点的左子节点置为空,再将当前节点赋值给 $prev$,以便于下一次遍历。 -同[面试题 17.12. BiNode](/lcci/17.12.BiNode/README.md)。 +遍历结束后,原二叉搜索树被修改成只有右子节点的单链表,我们再将虚拟节点 $dummy$ 的右子节点返回即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为二叉搜索树的节点个数。 @@ -70,8 +72,7 @@ class Solution: prev = root dfs(root.right) - dummy = TreeNode(val=0, right=root) - prev = dummy + dummy = prev = TreeNode(right=root) dfs(root) return dummy.right ``` @@ -134,23 +135,22 @@ class Solution { */ class Solution { public: - TreeNode* prev; - TreeNode* increasingBST(TreeNode* root) { TreeNode* dummy = new TreeNode(0, nullptr, root); - prev = dummy; + TreeNode* prev = dummy; + function dfs = [&](TreeNode* root) { + if (!root) { + return; + } + dfs(root->left); + prev->right = root; + root->left = nullptr; + prev = root; + dfs(root->right); + }; dfs(root); return dummy->right; } - - void dfs(TreeNode* root) { - if (!root) return; - dfs(root->left); - prev->right = root; - root->left = nullptr; - prev = root; - dfs(root->right); - } }; ``` @@ -184,6 +184,41 @@ func increasingBST(root *TreeNode) *TreeNode { } ``` +### **TypeScript** + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function increasingBST(root: TreeNode | null): TreeNode | null { + const dummy = new TreeNode((right = root)); + let prev = dummy; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; + } + dfs(root.left); + prev.right = root; + root.left = null; + prev = root; + dfs(root.right); + }; + dfs(root); + return dummy.right; +} +``` + ### **...** ``` diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md b/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md index 1fbfc83922eb7..4ca4c7f6e8765 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md +++ b/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md @@ -31,7 +31,15 @@ ## Solutions -See [17.12. BiNode](/lcci/17.12.BiNode/README_EN.md). +**Solution 1: DFS In-order Traversal** + +We define a virtual node $dummy$, initially the right child of $dummy$ points to the root node $root$, and a pointer $prev$ points to $dummy$. + +We perform an in-order traversal on the binary search tree. During the traversal, each time we visit a node, we point the right child of $prev$ to it, then set the left child of the current node to null, and assign the current node to $prev$ for the next traversal. + +After the traversal ends, the original binary search tree is modified into a singly linked list with only right child nodes. We then return the right child of the virtual node $dummy$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes in the binary search tree. @@ -56,8 +64,7 @@ class Solution: prev = root dfs(root.right) - dummy = TreeNode(val=0, right=root) - prev = dummy + dummy = prev = TreeNode(right=root) dfs(root) return dummy.right ``` @@ -118,23 +125,22 @@ class Solution { */ class Solution { public: - TreeNode* prev; - TreeNode* increasingBST(TreeNode* root) { TreeNode* dummy = new TreeNode(0, nullptr, root); - prev = dummy; + TreeNode* prev = dummy; + function dfs = [&](TreeNode* root) { + if (!root) { + return; + } + dfs(root->left); + prev->right = root; + root->left = nullptr; + prev = root; + dfs(root->right); + }; dfs(root); return dummy->right; } - - void dfs(TreeNode* root) { - if (!root) return; - dfs(root->left); - prev->right = root; - root->left = nullptr; - prev = root; - dfs(root->right); - } }; ``` @@ -168,6 +174,41 @@ func increasingBST(root *TreeNode) *TreeNode { } ``` +### **TypeScript** + +```ts +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function increasingBST(root: TreeNode | null): TreeNode | null { + const dummy = new TreeNode((right = root)); + let prev = dummy; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; + } + dfs(root.left); + prev.right = root; + root.left = null; + prev = root; + dfs(root.right); + }; + dfs(root); + return dummy.right; +} +``` + ### **...** ``` diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp index 6e0fe2b90aa0d..5ce6df7ace97d 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp +++ b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp @@ -11,21 +11,20 @@ */ class Solution { public: - TreeNode* prev; - TreeNode* increasingBST(TreeNode* root) { TreeNode* dummy = new TreeNode(0, nullptr, root); - prev = dummy; + TreeNode* prev = dummy; + function dfs = [&](TreeNode* root) { + if (!root) { + return; + } + dfs(root->left); + prev->right = root; + root->left = nullptr; + prev = root; + dfs(root->right); + }; dfs(root); return dummy->right; } - - void dfs(TreeNode* root) { - if (!root) return; - dfs(root->left); - prev->right = root; - root->left = nullptr; - prev = root; - dfs(root->right); - } }; \ No newline at end of file diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.py b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.py index c21ff89ffbc9f..2ef6d7690b328 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.py +++ b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.py @@ -16,7 +16,6 @@ def dfs(root): prev = root dfs(root.right) - dummy = TreeNode(val=0, right=root) - prev = dummy + dummy = prev = TreeNode(right=root) dfs(root) return dummy.right diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.ts b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.ts new file mode 100644 index 0000000000000..f9e781ac63d18 --- /dev/null +++ b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.ts @@ -0,0 +1,30 @@ +/** + * Definition for a binary tree node. + * class TreeNode { + * val: number + * left: TreeNode | null + * right: TreeNode | null + * constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { + * this.val = (val===undefined ? 0 : val) + * this.left = (left===undefined ? null : left) + * this.right = (right===undefined ? null : right) + * } + * } + */ + +function increasingBST(root: TreeNode | null): TreeNode | null { + const dummy = new TreeNode((right = root)); + let prev = dummy; + const dfs = (root: TreeNode | null) => { + if (!root) { + return; + } + dfs(root.left); + prev.right = root; + root.left = null; + prev = root; + dfs(root.right); + }; + dfs(root); + return dummy.right; +} diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/README.md b/solution/0800-0899/0898.Bitwise ORs of Subarrays/README.md index becfa51d487e8..8ab819ca5bb84 100644 --- a/solution/0800-0899/0898.Bitwise ORs of Subarrays/README.md +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/README.md @@ -56,6 +56,18 @@ +**方法一:哈希表** + +题目求的是子数组按位或操作的结果的数量,如果我们枚举子数组的结束位置 $i$,那么以 $i-1$ 结尾的子数组按位或操作的结果的数量最多不超过 $32$ 个。这是因为,按位或是一个单调递增的操作。 + +因此,我们用一个哈希表 $ans$ 记录所有子数组按位或操作的结果,用一个哈希表 $s$ 记录以当前元素结尾的子数组按位或操作的结果,初始时 $s$ 只包含一个元素 $0$。 + +接下来,我们枚举子数组的结束位置 $i$,那么以 $i$ 结尾的子数组按位或操作的结果,是以 $i-1$ 结尾的子数组按位或操作的结果与 $a[i]$ 进行按位或操作的结果的集合,再加上 $a[i]$ 本身。我们用一个哈希表 $t$ 记录以 $i$ 结尾的子数组按位或操作的结果,然后我们更新 $s = t$,并将 $t$ 中的所有元素加入 $ans$。 + +最终,我们返回哈希表 $ans$ 中元素的数量即可。 + +时间复杂度 $O(n \times \log M)$,空间复杂度 $O(n \times \log M)$。其中 $n$ 和 $M$ 分别为数组长度和数组中元素的最大值。 + ### **Python3** @@ -65,17 +77,12 @@ ```python class Solution: def subarrayBitwiseORs(self, arr: List[int]) -> int: - s = set() - prev = 0 - for i, v in enumerate(arr): - prev |= v - curr = 0 - for j in range(i, -1, -1): - curr |= arr[j] - s.add(curr) - if curr == prev: - break - return len(s) + s = {0} + ans = set() + for x in arr: + s = {x | y for y in s} | {x} + ans |= s + return len(ans) ``` ### **Java** @@ -86,19 +93,18 @@ class Solution: class Solution { public int subarrayBitwiseORs(int[] arr) { Set s = new HashSet<>(); - int prev = 0; - for (int i = 0; i < arr.length; ++i) { - prev |= arr[i]; - int curr = 0; - for (int j = i; j >= 0; --j) { - curr |= arr[j]; - s.add(curr); - if (curr == prev) { - break; - } + s.add(0); + Set ans = new HashSet<>(); + for (int x : arr) { + Set t = new HashSet<>(); + for (int y : s) { + t.add(x | y); } + t.add(x); + s = t; + ans.addAll(s); } - return s.size(); + return ans.size(); } } ``` @@ -109,18 +115,17 @@ class Solution { class Solution { public: int subarrayBitwiseORs(vector& arr) { - unordered_set s; - int prev = 0; - for (int i = 0; i < arr.size(); ++i) { - prev |= arr[i]; - int curr = 0; - for (int j = i; ~j; --j) { - curr |= arr[j]; - s.insert(curr); - if (curr == prev) break; + unordered_set s{{0}}; + unordered_set ans; + for (int& x : arr) { + unordered_set t{{x}}; + for (int y : s) { + t.insert(x | y); } + s = move(t); + ans.insert(s.begin(), s.end()); } - return s.size(); + return ans.size(); } }; ``` @@ -129,20 +134,41 @@ public: ```go func subarrayBitwiseORs(arr []int) int { - s := map[int]bool{} - prev := 0 - for i, v := range arr { - prev |= v - curr := 0 - for j := i; j >= 0; j-- { - curr |= arr[j] - s[curr] = true - if curr == prev { - break - } + ans := map[int]bool{} + s := map[int]bool{0: true} + for _, x := range arr { + t := map[int]bool{x: true} + for y := range s { + t[x|y] = true + } + s = t + for y := range s { + ans[y] = true } } - return len(s) + return len(ans) +} +``` + +### **TypeScript** + +```ts +function subarrayBitwiseORs(arr: number[]): number { + const s: Set = new Set(); + const ans: Set = new Set(); + for (const x of arr) { + const t: Set = new Set(); + for (const y of s) { + t.add(x | y); + } + t.add(x); + s.clear(); + for (const y of t) { + s.add(y); + ans.add(y); + } + } + return ans.size; } ``` diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/README_EN.md b/solution/0800-0899/0898.Bitwise ORs of Subarrays/README_EN.md index bc6c6ed0edf5c..8cabaf183e7da 100644 --- a/solution/0800-0899/0898.Bitwise ORs of Subarrays/README_EN.md +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/README_EN.md @@ -47,6 +47,18 @@ There are 3 unique values, so the answer is 3. ## Solutions +**Solution 1: Hash Table** + +The problem asks for the number of unique bitwise OR operations results of subarrays. If we enumerate the end position $i$ of the subarray, the number of bitwise OR operations results of the subarray ending at $i-1$ does not exceed $32$. This is because the bitwise OR operation is a monotonically increasing operation. + +Therefore, we use a hash table $ans$ to record all the results of the bitwise OR operations of subarrays, and a hash table $s$ to record the results of the bitwise OR operations of subarrays ending with the current element. Initially, $s$ only contains one element $0$. + +Next, we enumerate the end position $i$ of the subarray. The result of the bitwise OR operation of the subarray ending at $i$ is the set of results of the bitwise OR operation of the subarray ending at $i-1$ and $a[i]$, plus $a[i]$ itself. We use a hash table $t$ to record the results of the bitwise OR operation of the subarray ending at $i$, then we update $s = t$, and add all elements in $t$ to $ans$. + +Finally, we return the number of elements in the hash table $ans$. + +The time complexity is $O(n \times \log M)$, and the space complexity is $O(n \times \log M)$. Here, $n$ and $M$ are the length of the array and the maximum value in the array, respectively. + ### **Python3** @@ -54,17 +66,12 @@ There are 3 unique values, so the answer is 3. ```python class Solution: def subarrayBitwiseORs(self, arr: List[int]) -> int: - s = set() - prev = 0 - for i, v in enumerate(arr): - prev |= v - curr = 0 - for j in range(i, -1, -1): - curr |= arr[j] - s.add(curr) - if curr == prev: - break - return len(s) + s = {0} + ans = set() + for x in arr: + s = {x | y for y in s} | {x} + ans |= s + return len(ans) ``` ### **Java** @@ -73,19 +80,18 @@ class Solution: class Solution { public int subarrayBitwiseORs(int[] arr) { Set s = new HashSet<>(); - int prev = 0; - for (int i = 0; i < arr.length; ++i) { - prev |= arr[i]; - int curr = 0; - for (int j = i; j >= 0; --j) { - curr |= arr[j]; - s.add(curr); - if (curr == prev) { - break; - } + s.add(0); + Set ans = new HashSet<>(); + for (int x : arr) { + Set t = new HashSet<>(); + for (int y : s) { + t.add(x | y); } + t.add(x); + s = t; + ans.addAll(s); } - return s.size(); + return ans.size(); } } ``` @@ -94,20 +100,20 @@ class Solution { ```cpp class Solution { +class Solution { public: int subarrayBitwiseORs(vector& arr) { - unordered_set s; - int prev = 0; - for (int i = 0; i < arr.size(); ++i) { - prev |= arr[i]; - int curr = 0; - for (int j = i; ~j; --j) { - curr |= arr[j]; - s.insert(curr); - if (curr == prev) break; + unordered_set s{{0}}; + unordered_set ans; + for (int& x : arr) { + unordered_set t{{x}}; + for (int y : s) { + t.insert(x | y); } + s = move(t); + ans.insert(s.begin(), s.end()); } - return s.size(); + return ans.size(); } }; ``` @@ -116,20 +122,41 @@ public: ```go func subarrayBitwiseORs(arr []int) int { - s := map[int]bool{} - prev := 0 - for i, v := range arr { - prev |= v - curr := 0 - for j := i; j >= 0; j-- { - curr |= arr[j] - s[curr] = true - if curr == prev { - break - } + ans := map[int]bool{} + s := map[int]bool{0: true} + for _, x := range arr { + t := map[int]bool{x: true} + for y := range s { + t[x|y] = true + } + s = t + for y := range s { + ans[y] = true } } - return len(s) + return len(ans) +} +``` + +### **TypeScript** + +```ts +function subarrayBitwiseORs(arr: number[]): number { + const s: Set = new Set(); + const ans: Set = new Set(); + for (const x of arr) { + const t: Set = new Set(); + for (const y of s) { + t.add(x | y); + } + t.add(x); + s.clear(); + for (const y of t) { + s.add(y); + ans.add(y); + } + } + return ans.size; } ``` diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.cpp b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.cpp index 597fe0531bfc7..fcff01a405c7e 100644 --- a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.cpp +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.cpp @@ -1,17 +1,16 @@ -class Solution { -public: - int subarrayBitwiseORs(vector& arr) { - unordered_set s; - int prev = 0; - for (int i = 0; i < arr.size(); ++i) { - prev |= arr[i]; - int curr = 0; - for (int j = i; ~j; --j) { - curr |= arr[j]; - s.insert(curr); - if (curr == prev) break; - } - } - return s.size(); - } +class Solution { +public: + int subarrayBitwiseORs(vector& arr) { + unordered_set s{{0}}; + unordered_set ans; + for (int& x : arr) { + unordered_set t{{x}}; + for (int y : s) { + t.insert(x | y); + } + s = move(t); + ans.insert(s.begin(), s.end()); + } + return ans.size(); + } }; \ No newline at end of file diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.go b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.go index d10e72407f32d..b2c176e2064ed 100644 --- a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.go +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.go @@ -1,16 +1,15 @@ func subarrayBitwiseORs(arr []int) int { - s := map[int]bool{} - prev := 0 - for i, v := range arr { - prev |= v - curr := 0 - for j := i; j >= 0; j-- { - curr |= arr[j] - s[curr] = true - if curr == prev { - break - } + ans := map[int]bool{} + s := map[int]bool{0: true} + for _, x := range arr { + t := map[int]bool{x: true} + for y := range s { + t[x|y] = true + } + s = t + for y := range s { + ans[y] = true } } - return len(s) + return len(ans) } \ No newline at end of file diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.java b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.java index 7628e4a7001a5..8749f8515d355 100644 --- a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.java +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.java @@ -1,18 +1,17 @@ -class Solution { - public int subarrayBitwiseORs(int[] arr) { - Set s = new HashSet<>(); - int prev = 0; - for (int i = 0; i < arr.length; ++i) { - prev |= arr[i]; - int curr = 0; - for (int j = i; j >= 0; --j) { - curr |= arr[j]; - s.add(curr); - if (curr == prev) { - break; - } - } - } - return s.size(); - } +class Solution { + public int subarrayBitwiseORs(int[] arr) { + Set s = new HashSet<>(); + s.add(0); + Set ans = new HashSet<>(); + for (int x : arr) { + Set t = new HashSet<>(); + for (int y : s) { + t.add(x | y); + } + t.add(x); + s = t; + ans.addAll(s); + } + return ans.size(); + } } \ No newline at end of file diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.py b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.py index 4493b31bcf034..4400928eb8e5a 100644 --- a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.py +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.py @@ -1,13 +1,8 @@ -class Solution: - def subarrayBitwiseORs(self, arr: List[int]) -> int: - s = set() - prev = 0 - for i, v in enumerate(arr): - prev |= v - curr = 0 - for j in range(i, -1, -1): - curr |= arr[j] - s.add(curr) - if curr == prev: - break - return len(s) +class Solution: + def subarrayBitwiseORs(self, arr: List[int]) -> int: + s = {0} + ans = set() + for x in arr: + s = {x | y for y in s} | {x} + ans |= s + return len(ans) diff --git a/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.ts b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.ts new file mode 100644 index 0000000000000..1794487d4b566 --- /dev/null +++ b/solution/0800-0899/0898.Bitwise ORs of Subarrays/Solution.ts @@ -0,0 +1,17 @@ +function subarrayBitwiseORs(arr: number[]): number { + const s: Set = new Set(); + const ans: Set = new Set(); + for (const x of arr) { + const t: Set = new Set(); + for (const y of s) { + t.add(x | y); + } + t.add(x); + s.clear(); + for (const y of t) { + s.add(y); + ans.add(y); + } + } + return ans.size; +} From 71c5a6b1e4f1481cc5a998d0e870355f1bb794d1 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 16 Dec 2023 18:28:01 +0800 Subject: [PATCH 2/2] fix: cpp code --- solution/0800-0899/0897.Increasing Order Search Tree/README.md | 2 +- .../0800-0899/0897.Increasing Order Search Tree/README_EN.md | 2 +- .../0800-0899/0897.Increasing Order Search Tree/Solution.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/README.md b/solution/0800-0899/0897.Increasing Order Search Tree/README.md index a7d3fdbcdd2a6..43916c8c85560 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/README.md +++ b/solution/0800-0899/0897.Increasing Order Search Tree/README.md @@ -138,7 +138,7 @@ public: TreeNode* increasingBST(TreeNode* root) { TreeNode* dummy = new TreeNode(0, nullptr, root); TreeNode* prev = dummy; - function dfs = [&](TreeNode* root) { + function dfs = [&](TreeNode* root) { if (!root) { return; } diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md b/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md index 4ca4c7f6e8765..8552be68c27c2 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md +++ b/solution/0800-0899/0897.Increasing Order Search Tree/README_EN.md @@ -128,7 +128,7 @@ public: TreeNode* increasingBST(TreeNode* root) { TreeNode* dummy = new TreeNode(0, nullptr, root); TreeNode* prev = dummy; - function dfs = [&](TreeNode* root) { + function dfs = [&](TreeNode* root) { if (!root) { return; } diff --git a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp index 5ce6df7ace97d..25a34d670957c 100644 --- a/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp +++ b/solution/0800-0899/0897.Increasing Order Search Tree/Solution.cpp @@ -14,7 +14,7 @@ class Solution { TreeNode* increasingBST(TreeNode* root) { TreeNode* dummy = new TreeNode(0, nullptr, root); TreeNode* prev = dummy; - function dfs = [&](TreeNode* root) { + function dfs = [&](TreeNode* root) { if (!root) { return; }