From 5d6b9e7cd3a1fd5e137f19220b9630e2527994e4 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sat, 16 Dec 2023 18:39:37 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problems: No.0896~0898 (#2107) * 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..43916c8c85560 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..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 @@ -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..25a34d670957c 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 894bb7d8969e1104ddf4c8fa0e85b3d741aab355 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sat, 16 Dec 2023 20:18:30 +0800 Subject: [PATCH 2/2] feat: add solutions to lc problems: No.0899~0908 (#2108) * No.0899.Orderly Queue * No.0900.RLE Iterator * No.0901.Online Stock Span * No.0903.Valid Permutations for DI Sequence * No.0904.Fruit Into Baskets * No.0905.Sort Array By Parity --- .../0800-0899/0899.Orderly Queue/README.md | 10 +- .../0800-0899/0899.Orderly Queue/README_EN.md | 14 ++ .../0900-0999/0900.RLE Iterator/README.md | 100 +++++++---- .../0900-0999/0900.RLE Iterator/README_EN.md | 100 +++++++---- .../0900-0999/0900.RLE Iterator/Solution.cpp | 61 ++++--- .../0900-0999/0900.RLE Iterator/Solution.go | 13 +- .../0900-0999/0900.RLE Iterator/Solution.java | 58 ++++--- .../0900-0999/0900.RLE Iterator/Solution.py | 42 ++--- .../0900-0999/0900.RLE Iterator/Solution.ts | 31 ++++ .../0901.Online Stock Span/README.md | 2 +- .../0901.Online Stock Span/README_EN.md | 10 +- .../README_EN.md | 16 ++ .../0904.Fruit Into Baskets/README_EN.md | 34 ++++ .../0905.Sort Array By Parity/README.md | 155 +++++++++++------- .../0905.Sort Array By Parity/README_EN.md | 155 ++++++++++++------ .../0905.Sort Array By Parity/Solution.cpp | 26 +-- .../0905.Sort Array By Parity/Solution.go | 7 +- .../0905.Sort Array By Parity/Solution.java | 32 ++-- .../0905.Sort Array By Parity/Solution.js | 7 +- .../0905.Sort Array By Parity/Solution.py | 22 +-- .../0905.Sort Array By Parity/Solution.rs | 18 +- .../0905.Sort Array By Parity/Solution.ts | 14 ++ .../0900-0999/0908.Smallest Range I/README.md | 5 +- .../0908.Smallest Range I/README_EN.md | 5 +- .../0908.Smallest Range I/Solution.cpp | 13 +- 25 files changed, 623 insertions(+), 327 deletions(-) create mode 100644 solution/0900-0999/0900.RLE Iterator/Solution.ts create mode 100644 solution/0900-0999/0905.Sort Array By Parity/Solution.ts diff --git a/solution/0800-0899/0899.Orderly Queue/README.md b/solution/0800-0899/0899.Orderly Queue/README.md index 9ac0b776845fd..36946c4f74e38 100644 --- a/solution/0800-0899/0899.Orderly Queue/README.md +++ b/solution/0800-0899/0899.Orderly Queue/README.md @@ -49,13 +49,15 @@ 对于任何字符串,如果可以交换任意相邻字符,则可以对字符串中的字符做类似冒泡排序的操作,最终得到一个升序排列的字符串。 -**方法一:分类判断** +**方法一:分情况判断** -若 $k=1$,我们每次只能将字符串首字符移动到字符串末尾,总共有 $s.length$ 种不同的状态,我们返回其中字典序最小的字符串即可。 +若 $k = 1$,我们每次只能将字符串首字符移动到字符串末尾,总共有 $|s|$ 种不同的状态,我们返回其中字典序最小的字符串即可。 -若 $k\gt1$,对于形如 $abc[xy]def$ 的字符串,可以依次将 $a$, $b$, $c$ 移动到最后,得到 $[xy]defabc$,然后将 $y$, $x$ 移动到最后,得到 $defabc[yx]$,最后将 $d$, $e$, $f$ 移动到最后,得到 $abc[yx]def$,这样就实现了对 $y$, $x$ 的交换。 +若 $k \gt 1$,对于形如 $abc[xy]def$ 的字符串,可以依次将 $a$, $b$, $c$ 移动到最后,得到 $[xy]defabc$,然后将 $y$, $x$ 移动到最后,得到 $defabc[yx]$,最后将 $d$, $e$, $f$ 移动到最后,得到 $abc[yx]def$,这样就实现了对 $y$, $x$ 的交换。 -因此,只要 $k\gt1$,我们就能够交换字符串中的任何两个相邻字符,最终得到一个升序排列的字符串。 +因此,只要 $k \gt 1$,我们就能够交换字符串中的任何两个相邻字符,最终得到一个升序排列的字符串。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 是字符串的长度。 diff --git a/solution/0800-0899/0899.Orderly Queue/README_EN.md b/solution/0800-0899/0899.Orderly Queue/README_EN.md index 8ada9f00ca1d4..e4b639e9a32a5 100644 --- a/solution/0800-0899/0899.Orderly Queue/README_EN.md +++ b/solution/0800-0899/0899.Orderly Queue/README_EN.md @@ -39,6 +39,20 @@ In the second move, we move the 3rd character 'c' to the end, ## Solutions +**Preface** + +For any string, if any adjacent characters can be swapped, we can perform a bubble sort-like operation on the characters in the string, eventually obtaining a string sorted in ascending order. + +**Solution 1: Case-by-case Judgment** + +If $k = 1$, we can only move the first character of the string to the end of the string each time, resulting in $|s|$ different states. We return the string with the smallest lexicographic order. + +If $k > 1$, for a string like $abc[xy]def$, we can move $a$, $b$, and $c$ to the end in order, resulting in $[xy]defabc$. Then we move $y$ and $x$ to the end, resulting in $defabc[yx]$. Finally, we move $d$, $e$, and $f$ to the end, resulting in $abc[yx]def$. This way, we have swapped $y$ and $x$. + +Therefore, as long as $k > 1$, we can swap any two adjacent characters in the string, eventually obtaining a string sorted in ascending order. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string. + ### **Python3** diff --git a/solution/0900-0999/0900.RLE Iterator/README.md b/solution/0900-0999/0900.RLE Iterator/README.md index 0048f2c463356..491170fb222b8 100644 --- a/solution/0900-0999/0900.RLE Iterator/README.md +++ b/solution/0900-0999/0900.RLE Iterator/README.md @@ -56,6 +56,16 @@ rLEIterator.next(2); // 耗去序列的 2 个项,返回 -1。 这是由于第 +**方法一:维护两个指针** + +我们定义两个指针 $i$ 和 $j$,其中指针 $i$ 指向当前读取的游程编码,指针 $j$ 指向当前读取的游程编码中的第几个字符。初始时 $i = 0$, $j = 0$。 + +每次调用 `next(n)` 时,我们判断当前游程编码中剩余的字符数 $encoding[i] - j$ 是否小于 $n$,若是,则将 $n$ 减去 $encoding[i] - j$,并将 $i$ 加 $2$,$j$ 置为 $0$,然后继续判断下一个游程编码;若不是,则将 $j$ 加 $n$,并返回 $encoding[i + 1]$。 + +若 $i$ 超出了游程编码的长度,依然没有返回值,则说明没有剩余的元素要耗尽,返回 $-1$。 + +时间复杂度 $O(n + q)$,空间复杂度 $O(n)$。其中 $n$ 是游程编码的长度,而 $q$ 是调用 `next(n)` 的次数。 + ### **Python3** @@ -67,16 +77,16 @@ class RLEIterator: def __init__(self, encoding: List[int]): self.encoding = encoding self.i = 0 - self.curr = 0 + self.j = 0 def next(self, n: int) -> int: while self.i < len(self.encoding): - if self.curr + n > self.encoding[self.i]: - n -= self.encoding[self.i] - self.curr - self.curr = 0 + if self.encoding[self.i] - self.j < n: + n -= self.encoding[self.i] - self.j self.i += 2 + self.j = 0 else: - self.curr += n + self.j += n return self.encoding[self.i + 1] return -1 @@ -93,23 +103,21 @@ class RLEIterator: ```java class RLEIterator { private int[] encoding; - private int curr; private int i; + private int j; public RLEIterator(int[] encoding) { this.encoding = encoding; - curr = 0; - i = 0; } public int next(int n) { while (i < encoding.length) { - if (curr + n > encoding[i]) { - n -= encoding[i] - curr; + if (encoding[i] - j < n) { + n -= (encoding[i] - j); i += 2; - curr = 0; + j = 0; } else { - curr += n; + j += n; return encoding[i + 1]; } } @@ -129,29 +137,28 @@ class RLEIterator { ```cpp class RLEIterator { public: - vector encoding; - int curr; - int i; - RLEIterator(vector& encoding) { this->encoding = encoding; - this->curr = 0; - this->i = 0; } int next(int n) { while (i < encoding.size()) { - if (curr + n > encoding[i]) { - n -= encoding[i] - curr; - curr = 0; + if (encoding[i] - j < n) { + n -= (encoding[i] - j); i += 2; + j = 0; } else { - curr += n; + j += n; return encoding[i + 1]; } } return -1; } + +private: + vector encoding; + int i = 0; + int j = 0; }; /** @@ -166,22 +173,21 @@ public: ```go type RLEIterator struct { encoding []int - curr int - i int + i, j int } func Constructor(encoding []int) RLEIterator { - return RLEIterator{encoding: encoding, curr: 0, i: 0} + return RLEIterator{encoding, 0, 0} } func (this *RLEIterator) Next(n int) int { for this.i < len(this.encoding) { - if this.curr+n > this.encoding[this.i] { - n -= this.encoding[this.i] - this.curr - this.curr = 0 + if this.encoding[this.i]-this.j < n { + n -= (this.encoding[this.i] - this.j) this.i += 2 + this.j = 0 } else { - this.curr += n + this.j += n return this.encoding[this.i+1] } } @@ -195,6 +201,42 @@ func (this *RLEIterator) Next(n int) int { */ ``` +### **TypeScript** + +```ts +class RLEIterator { + private encoding: number[]; + private i: number; + private j: number; + + constructor(encoding: number[]) { + this.encoding = encoding; + this.i = 0; + this.j = 0; + } + + next(n: number): number { + while (this.i < this.encoding.length) { + if (this.encoding[this.i] - this.j < n) { + n -= this.encoding[this.i] - this.j; + this.i += 2; + this.j = 0; + } else { + this.j += n; + return this.encoding[this.i + 1]; + } + } + return -1; + } +} + +/** + * Your RLEIterator object will be instantiated and called as such: + * var obj = new RLEIterator(encoding) + * var param_1 = obj.next(n) + */ +``` + ### **...** ``` diff --git a/solution/0900-0999/0900.RLE Iterator/README_EN.md b/solution/0900-0999/0900.RLE Iterator/README_EN.md index 136e05deb08bc..d1c2ef60728ef 100644 --- a/solution/0900-0999/0900.RLE Iterator/README_EN.md +++ b/solution/0900-0999/0900.RLE Iterator/README_EN.md @@ -51,6 +51,16 @@ but the second term did not exist. Since the last term exhausted does not exist, ## Solutions +**Solution 1: Maintain Two Pointers** + +We define two pointers $i$ and $j$, where pointer $i$ points to the current run-length encoding being read, and pointer $j$ points to which character in the current run-length encoding is being read. Initially, $i = 0$, $j = 0$. + +Each time we call `next(n)`, we judge whether the remaining number of characters in the current run-length encoding $encoding[i] - j$ is less than $n$. If it is, we subtract $n$ by $encoding[i] - j$, add $2$ to $i$, and set $j$ to $0$, then continue to judge the next run-length encoding. If it is not, we add $n$ to $j$ and return $encoding[i + 1]$. + +If $i$ exceeds the length of the run-length encoding and there is still no return value, it means that there are no remaining elements to be exhausted, and we return $-1$. + +The time complexity is $O(n + q)$, and the space complexity is $O(n)$. Here, $n$ is the length of the run-length encoding, and $q$ is the number of times `next(n)` is called. + ### **Python3** @@ -60,16 +70,16 @@ class RLEIterator: def __init__(self, encoding: List[int]): self.encoding = encoding self.i = 0 - self.curr = 0 + self.j = 0 def next(self, n: int) -> int: while self.i < len(self.encoding): - if self.curr + n > self.encoding[self.i]: - n -= self.encoding[self.i] - self.curr - self.curr = 0 + if self.encoding[self.i] - self.j < n: + n -= self.encoding[self.i] - self.j self.i += 2 + self.j = 0 else: - self.curr += n + self.j += n return self.encoding[self.i + 1] return -1 @@ -84,23 +94,21 @@ class RLEIterator: ```java class RLEIterator { private int[] encoding; - private int curr; private int i; + private int j; public RLEIterator(int[] encoding) { this.encoding = encoding; - curr = 0; - i = 0; } public int next(int n) { while (i < encoding.length) { - if (curr + n > encoding[i]) { - n -= encoding[i] - curr; + if (encoding[i] - j < n) { + n -= (encoding[i] - j); i += 2; - curr = 0; + j = 0; } else { - curr += n; + j += n; return encoding[i + 1]; } } @@ -120,29 +128,28 @@ class RLEIterator { ```cpp class RLEIterator { public: - vector encoding; - int curr; - int i; - RLEIterator(vector& encoding) { this->encoding = encoding; - this->curr = 0; - this->i = 0; } int next(int n) { while (i < encoding.size()) { - if (curr + n > encoding[i]) { - n -= encoding[i] - curr; - curr = 0; + if (encoding[i] - j < n) { + n -= (encoding[i] - j); i += 2; + j = 0; } else { - curr += n; + j += n; return encoding[i + 1]; } } return -1; } + +private: + vector encoding; + int i = 0; + int j = 0; }; /** @@ -157,22 +164,21 @@ public: ```go type RLEIterator struct { encoding []int - curr int - i int + i, j int } func Constructor(encoding []int) RLEIterator { - return RLEIterator{encoding: encoding, curr: 0, i: 0} + return RLEIterator{encoding, 0, 0} } func (this *RLEIterator) Next(n int) int { for this.i < len(this.encoding) { - if this.curr+n > this.encoding[this.i] { - n -= this.encoding[this.i] - this.curr - this.curr = 0 + if this.encoding[this.i]-this.j < n { + n -= (this.encoding[this.i] - this.j) this.i += 2 + this.j = 0 } else { - this.curr += n + this.j += n return this.encoding[this.i+1] } } @@ -186,6 +192,42 @@ func (this *RLEIterator) Next(n int) int { */ ``` +### **TypeScript** + +```ts +class RLEIterator { + private encoding: number[]; + private i: number; + private j: number; + + constructor(encoding: number[]) { + this.encoding = encoding; + this.i = 0; + this.j = 0; + } + + next(n: number): number { + while (this.i < this.encoding.length) { + if (this.encoding[this.i] - this.j < n) { + n -= this.encoding[this.i] - this.j; + this.i += 2; + this.j = 0; + } else { + this.j += n; + return this.encoding[this.i + 1]; + } + } + return -1; + } +} + +/** + * Your RLEIterator object will be instantiated and called as such: + * var obj = new RLEIterator(encoding) + * var param_1 = obj.next(n) + */ +``` + ### **...** ``` diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.cpp b/solution/0900-0999/0900.RLE Iterator/Solution.cpp index 702f94303f459..55f97fd09bde5 100644 --- a/solution/0900-0999/0900.RLE Iterator/Solution.cpp +++ b/solution/0900-0999/0900.RLE Iterator/Solution.cpp @@ -1,32 +1,31 @@ -class RLEIterator { -public: - vector encoding; - int curr; - int i; - - RLEIterator(vector& encoding) { - this->encoding = encoding; - this->curr = 0; - this->i = 0; - } - - int next(int n) { - while (i < encoding.size()) { - if (curr + n > encoding[i]) { - n -= encoding[i] - curr; - curr = 0; - i += 2; - } else { - curr += n; - return encoding[i + 1]; - } - } - return -1; - } -}; - -/** - * Your RLEIterator object will be instantiated and called as such: - * RLEIterator* obj = new RLEIterator(encoding); - * int param_1 = obj->next(n); +class RLEIterator { +public: + RLEIterator(vector& encoding) { + this->encoding = encoding; + } + + int next(int n) { + while (i < encoding.size()) { + if (encoding[i] - j < n) { + n -= (encoding[i] - j); + i += 2; + j = 0; + } else { + j += n; + return encoding[i + 1]; + } + } + return -1; + } + +private: + vector encoding; + int i = 0; + int j = 0; +}; + +/** + * Your RLEIterator object will be instantiated and called as such: + * RLEIterator* obj = new RLEIterator(encoding); + * int param_1 = obj->next(n); */ \ No newline at end of file diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.go b/solution/0900-0999/0900.RLE Iterator/Solution.go index 7f3257014e503..284355b492f3b 100644 --- a/solution/0900-0999/0900.RLE Iterator/Solution.go +++ b/solution/0900-0999/0900.RLE Iterator/Solution.go @@ -1,21 +1,20 @@ type RLEIterator struct { encoding []int - curr int - i int + i, j int } func Constructor(encoding []int) RLEIterator { - return RLEIterator{encoding: encoding, curr: 0, i: 0} + return RLEIterator{encoding, 0, 0} } func (this *RLEIterator) Next(n int) int { for this.i < len(this.encoding) { - if this.curr+n > this.encoding[this.i] { - n -= this.encoding[this.i] - this.curr - this.curr = 0 + if this.encoding[this.i]-this.j < n { + n -= (this.encoding[this.i] - this.j) this.i += 2 + this.j = 0 } else { - this.curr += n + this.j += n return this.encoding[this.i+1] } } diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.java b/solution/0900-0999/0900.RLE Iterator/Solution.java index 865643d5f63a7..94f0ad4d82376 100644 --- a/solution/0900-0999/0900.RLE Iterator/Solution.java +++ b/solution/0900-0999/0900.RLE Iterator/Solution.java @@ -1,31 +1,29 @@ -class RLEIterator { - private int[] encoding; - private int curr; - private int i; - - public RLEIterator(int[] encoding) { - this.encoding = encoding; - curr = 0; - i = 0; - } - - public int next(int n) { - while (i < encoding.length) { - if (curr + n > encoding[i]) { - n -= encoding[i] - curr; - i += 2; - curr = 0; - } else { - curr += n; - return encoding[i + 1]; - } - } - return -1; - } -} - -/** - * Your RLEIterator object will be instantiated and called as such: - * RLEIterator obj = new RLEIterator(encoding); - * int param_1 = obj.next(n); +class RLEIterator { + private int[] encoding; + private int i; + private int j; + + public RLEIterator(int[] encoding) { + this.encoding = encoding; + } + + public int next(int n) { + while (i < encoding.length) { + if (encoding[i] - j < n) { + n -= (encoding[i] - j); + i += 2; + j = 0; + } else { + j += n; + return encoding[i + 1]; + } + } + return -1; + } +} + +/** + * Your RLEIterator object will be instantiated and called as such: + * RLEIterator obj = new RLEIterator(encoding); + * int param_1 = obj.next(n); */ \ No newline at end of file diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.py b/solution/0900-0999/0900.RLE Iterator/Solution.py index dae2a3aafaac3..0344fbf233712 100644 --- a/solution/0900-0999/0900.RLE Iterator/Solution.py +++ b/solution/0900-0999/0900.RLE Iterator/Solution.py @@ -1,21 +1,21 @@ -class RLEIterator: - def __init__(self, encoding: List[int]): - self.encoding = encoding - self.i = 0 - self.curr = 0 - - def next(self, n: int) -> int: - while self.i < len(self.encoding): - if self.curr + n > self.encoding[self.i]: - n -= self.encoding[self.i] - self.curr - self.curr = 0 - self.i += 2 - else: - self.curr += n - return self.encoding[self.i + 1] - return -1 - - -# Your RLEIterator object will be instantiated and called as such: -# obj = RLEIterator(encoding) -# param_1 = obj.next(n) +class RLEIterator: + def __init__(self, encoding: List[int]): + self.encoding = encoding + self.i = 0 + self.j = 0 + + def next(self, n: int) -> int: + while self.i < len(self.encoding): + if self.encoding[self.i] - self.j < n: + n -= self.encoding[self.i] - self.j + self.i += 2 + self.j = 0 + else: + self.j += n + return self.encoding[self.i + 1] + return -1 + + +# Your RLEIterator object will be instantiated and called as such: +# obj = RLEIterator(encoding) +# param_1 = obj.next(n) diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.ts b/solution/0900-0999/0900.RLE Iterator/Solution.ts new file mode 100644 index 0000000000000..f6cd9a7324a14 --- /dev/null +++ b/solution/0900-0999/0900.RLE Iterator/Solution.ts @@ -0,0 +1,31 @@ +class RLEIterator { + private encoding: number[]; + private i: number; + private j: number; + + constructor(encoding: number[]) { + this.encoding = encoding; + this.i = 0; + this.j = 0; + } + + next(n: number): number { + while (this.i < this.encoding.length) { + if (this.encoding[this.i] - this.j < n) { + n -= this.encoding[this.i] - this.j; + this.i += 2; + this.j = 0; + } else { + this.j += n; + return this.encoding[this.i + 1]; + } + } + return -1; + } +} + +/** + * Your RLEIterator object will be instantiated and called as such: + * var obj = new RLEIterator(encoding) + * var param_1 = obj.next(n) + */ diff --git a/solution/0900-0999/0901.Online Stock Span/README.md b/solution/0900-0999/0901.Online Stock Span/README.md index bcc61c2cbc580..93e5295f512d0 100644 --- a/solution/0900-0999/0901.Online Stock Span/README.md +++ b/solution/0900-0999/0901.Online Stock Span/README.md @@ -70,7 +70,7 @@ stockSpanner.next(85); // 返回 6 最后将 $(price, cnt)$ 入栈,返回 $cnt$ 即可。 -时间复杂度 $O(n)$,其中 $n$ 为 $next$ 函数的调用次数。 +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是调用 `next(price)` 的次数。 diff --git a/solution/0900-0999/0901.Online Stock Span/README_EN.md b/solution/0900-0999/0901.Online Stock Span/README_EN.md index 46f7fc8ac0f07..977a1ad2d099f 100644 --- a/solution/0900-0999/0901.Online Stock Span/README_EN.md +++ b/solution/0900-0999/0901.Online Stock Span/README_EN.md @@ -53,17 +53,17 @@ stockSpanner.next(85); // return 6 **Solution 1: Monotonic Stack** -According to the problem description, we can know that for the price price on a certain day, we need to find the first price that is greater than price when looking back, and the difference between the indices of these two prices is the span of the price on that day. +Based on the problem description, we know that for the current day's price $price$, we start from this price and look backwards to find the first price that is larger than this price. The difference in indices $cnt$ between these two prices is the span of the current day's price. -This is actually a classic monotonic stack model, which finds the first element on the left that is greater than the current element. +This is actually a classic monotonic stack model, where we find the first element larger than the current element on the left. -We maintain a stack that is monotonically decreasing from the bottom to the top in terms of prices. Each element in the stack stores a pair of $(price, cnt)$, where $price$ represents the price, and $cnt$ represents the span of the current price. +We maintain a stack where the prices from the bottom to the top of the stack are monotonically decreasing. Each element in the stack is a $(price, cnt)$ data pair, where $price$ represents the price, and $cnt$ represents the span of the current price. -When encountering a price $price$, we compare it with the top element of the stack. If the price of the top element of the stack is less than or equal to price, we add the span cnt of the current price to the span of the top element of the stack, and then pop the top element of the stack until the price of the top element of the stack is greater than price, or the stack is empty. +When the price $price$ appears, we compare it with the top element of the stack. If the price of the top element of the stack is less than or equal to $price$, we add the span $cnt$ of the current day's price to the span of the top element of the stack, and then pop the top element of the stack. This continues until the price of the top element of the stack is greater than $price$, or the stack is empty. Finally, we push $(price, cnt)$ onto the stack and return $cnt$. -The time complexity is $O(n)$, where $n$ is the number of calls to the next function. +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of times `next(price)` is called. diff --git a/solution/0900-0999/0903.Valid Permutations for DI Sequence/README_EN.md b/solution/0900-0999/0903.Valid Permutations for DI Sequence/README_EN.md index 791bbe55bbce6..d036fb74360dc 100644 --- a/solution/0900-0999/0903.Valid Permutations for DI Sequence/README_EN.md +++ b/solution/0900-0999/0903.Valid Permutations for DI Sequence/README_EN.md @@ -52,6 +52,22 @@ ## Solutions +**Solution 1: Dynamic Programming** + +We define $f[i][j]$ as the number of permutations that satisfy the problem's requirements with the first $i$ characters of the string ending with the number $j$. Initially, $f[0][0]=1$, and the rest $f[0][j]=0$. The answer is $\sum_{j=0}^n f[n][j]$. + +Consider $f[i][j]$, where $j \in [0, i]$. + +If the $i$th character $s[i-1]$ is `'D'`, then $f[i][j]$ can be transferred from $f[i-1][k]$, where $k \in [j+1, i]$. Since $k-1$ can only be up to $i-1$, we move $k$ one place to the left, so $k \in [j, i-1]$. Therefore, we have $f[i][j] = \sum_{k=j}^{i-1} f[i-1][k]$. + +If the $i$th character $s[i-1]$ is `'I'`, then $f[i][j]$ can be transferred from $f[i-1][k]$, where $k \in [0, j-1]$. Therefore, we have $f[i][j] = \sum_{k=0}^{j-1} f[i-1][k]$. + +The final answer is $\sum_{j=0}^n f[n][j]$. + +The time complexity is $O(n^3)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string. + +We can optimize the time complexity to $O(n^2)$ using prefix sums. Additionally, we can optimize the space complexity to $O(n)$ using a rolling array. + ### **Python3** diff --git a/solution/0900-0999/0904.Fruit Into Baskets/README_EN.md b/solution/0900-0999/0904.Fruit Into Baskets/README_EN.md index 38d7556e466b7..7df4259b5996e 100644 --- a/solution/0900-0999/0904.Fruit Into Baskets/README_EN.md +++ b/solution/0900-0999/0904.Fruit Into Baskets/README_EN.md @@ -53,6 +53,40 @@ If we had started at the first tree, we would only pick from trees [1,2]. ## Solutions +**Solution 1: Hash Table + Sliding Window** + +We use a hash table $cnt$ to maintain the types and corresponding quantities of fruits in the current window, and use two pointers $j$ and $i$ to maintain the left and right boundaries of the window. + +We traverse the `fruits` array, add the current fruit $x$ to the window, i.e., $cnt[x]++$, then judge whether the types of fruits in the current window exceed $2$. If it exceeds $2$, we need to move the left boundary $j$ of the window to the right until the types of fruits in the window do not exceed $2$. Then we update the answer, i.e., $ans = \max(ans, i - j + 1)$. + +After the traversal ends, we can get the final answer. + +``` +1 2 3 2 2 1 4 +^ ^ +j i + + +1 2 3 2 2 1 4 + ^ ^ + j i + + +1 2 3 2 2 1 4 + ^ ^ + j i +``` + +The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the `fruits` array. + +**Solution 2: Sliding Window Optimization** + +In Solution 1, we find that the window size sometimes increases and sometimes decreases, which requires us to update the answer each time. + +But what this problem actually asks for is the maximum number of fruits, that is, the "largest" window. We don't need to shrink the window, we just need to let the window monotonically increase. So the code omits the operation of updating the answer each time, and only needs to return the size of the window as the answer after the traversal ends. + +The time complexity is $O(n)$, and the space complexity is $O(1)$. Here, $n$ is the length of the `fruits` array. + ### **Python3** diff --git a/solution/0900-0999/0905.Sort Array By Parity/README.md b/solution/0900-0999/0905.Sort Array By Parity/README.md index 305e8b69b58fe..a4cb1477e3919 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/README.md +++ b/solution/0900-0999/0905.Sort Array By Parity/README.md @@ -40,7 +40,17 @@ -双指针原地交换数组元素。 +**方法一:双指针** + +我们用两个指针 $i$ 和 $j$ 分别指向数组的首尾,当 $i < j$ 时,执行以下操作。 + +- 如果 $nums[i]$ 为偶数,则 $i$ 自增 $1$。 +- 如果 $nums[j]$ 为奇数,则 $j$ 自减 $1$。 +- 如果 $nums[i]$ 为奇数,且 $nums[j]$ 为偶数,则交换 $nums[i]$ 和 $nums[j]$。然后 $i$ 自增 $1$,而 $j$ 自减 $1$。 + +最后返回数组 $nums$ 即可。 + +时间复杂度 $O(n)$,其中 $n$ 是数组 $nums$ 的长度。空间复杂度 $O(1)$。 @@ -53,11 +63,13 @@ class Solution: def sortArrayByParity(self, nums: List[int]) -> List[int]: i, j = 0, len(nums) - 1 while i < j: - if nums[i] & 1: - nums[i], nums[j] = nums[j], nums[i] + if nums[i] % 2 == 0: + i += 1 + elif nums[j] % 2 == 1: j -= 1 else: - i += 1 + nums[i], nums[j] = nums[j], nums[i] + i, j = i + 1, j - 1 return nums ``` @@ -68,14 +80,18 @@ class Solution: ```java class Solution { public int[] sortArrayByParity(int[] nums) { - for (int i = 0, j = nums.length - 1; i < j;) { - if (nums[i] % 2 == 1) { + int i = 0, j = nums.length - 1; + while (i < j) { + if (nums[i] % 2 == 0) { + ++i; + } else if (nums[j] % 2 == 1) { + --j; + } else { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; - --j; - } else { ++i; + --j; } } return nums; @@ -83,57 +99,21 @@ class Solution { } ``` -### **JavaScript** - -```js -/** - * @param {number[]} nums - * @return {number[]} - */ -var sortArrayByParity = function (nums) { - for (let i = 0, j = nums.length - 1; i < j; ) { - if (nums[i] & 1) { - [nums[i], nums[j]] = [nums[j], nums[i]]; - --j; - } else { - ++i; - } - } - return nums; -}; -``` - -### **Rust** - -```rust -impl Solution { - pub fn sort_array_by_parity(mut nums: Vec) -> Vec { - let (mut l, mut r) = (0, nums.len() - 1); - while l < r { - while l < r && (nums[l] & 1) == 0 { - l += 1; - } - while l < r && (nums[r] & 1) == 1 { - r -= 1; - } - nums.swap(l, r); - } - nums - } -} -``` - ### **C++** ```cpp class Solution { public: vector sortArrayByParity(vector& nums) { - for (int i = 0, j = nums.size() - 1; i < j;) { - if (nums[i] & 1) - swap(nums[i], nums[j--]); - else + int i = 0, j = nums.size() - 1; + while (i < j) { + if (nums[i] % 2 == 0) { ++i; + } else if (nums[j] % 2 == 1) { + --j; + } else { + swap(nums[i++], nums[j--]); + } } return nums; } @@ -145,17 +125,82 @@ public: ```go func sortArrayByParity(nums []int) []int { for i, j := 0, len(nums)-1; i < j; { - if nums[i]%2 == 1 { - nums[i], nums[j] = nums[j], nums[i] + if nums[i]%2 == 0 { + i++ + } else if nums[j]%2 == 1 { j-- } else { - i++ + nums[i], nums[j] = nums[j], nums[i] } } return nums } ``` +### **Rust** + +```rust +impl Solution { + pub fn sort_array_by_parity(mut nums: Vec) -> Vec { + let (mut i, mut j) = (0, nums.len() - 1); + while i < j { + if nums[i] % 2 == 0 { + i += 1; + } else if nums[j] % 2 == 1 { + j -= 1; + } else { + nums.swap(i, j); + i += 1; + j -= 1; + } + } + nums + } +} +``` + +### **TypeScript** + +```ts +function sortArrayByParity(nums: number[]): number[] { + for (let i = 0, j = nums.length - 1; i < j; ) { + if (nums[i] % 2 === 0) { + ++i; + } else if (nums[j] % 2 === 1) { + --j; + } else { + [nums[i], nums[j]] = [nums[j], nums[i]]; + ++i; + --j; + } + } + return nums; +} +``` + +### **JavaScript** + +```js +/** + * @param {number[]} nums + * @return {number[]} + */ +var sortArrayByParity = function (nums) { + for (let i = 0, j = nums.length - 1; i < j; ) { + if (nums[i] % 2 === 0) { + ++i; + } else if (nums[j] % 2 === 1) { + --j; + } else { + [nums[i], nums[j]] = [nums[j], nums[i]]; + ++i; + --j; + } + } + return nums; +}; +``` + ### **...** ``` diff --git a/solution/0900-0999/0905.Sort Array By Parity/README_EN.md b/solution/0900-0999/0905.Sort Array By Parity/README_EN.md index cfd10228d78f7..ec74765888260 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/README_EN.md +++ b/solution/0900-0999/0905.Sort Array By Parity/README_EN.md @@ -34,6 +34,18 @@ ## Solutions +**Solution 1: Two Pointers** + +We use two pointers $i$ and $j$ to point to the beginning and end of the array respectively. When $i < j$, we perform the following operations. + +- If $nums[i]$ is even, then increment $i$ by $1$. +- If $nums[j]$ is odd, then decrement $j$ by $1$. +- If $nums[i]$ is odd and $nums[j]$ is even, then swap $nums[i]$ and $nums[j]$. Then increment $i$ by $1$, and decrement $j$ by $1$. + +Finally, return the array $nums$. + +The time complexity is $O(n)$, where $n$ is the length of the array $nums$. The space complexity is $O(1)$. + ### **Python3** @@ -43,11 +55,13 @@ class Solution: def sortArrayByParity(self, nums: List[int]) -> List[int]: i, j = 0, len(nums) - 1 while i < j: - if nums[i] & 1: - nums[i], nums[j] = nums[j], nums[i] + if nums[i] % 2 == 0: + i += 1 + elif nums[j] % 2 == 1: j -= 1 else: - i += 1 + nums[i], nums[j] = nums[j], nums[i] + i, j = i + 1, j - 1 return nums ``` @@ -56,14 +70,18 @@ class Solution: ```java class Solution { public int[] sortArrayByParity(int[] nums) { - for (int i = 0, j = nums.length - 1; i < j;) { - if (nums[i] % 2 == 1) { + int i = 0, j = nums.length - 1; + while (i < j) { + if (nums[i] % 2 == 0) { + ++i; + } else if (nums[j] % 2 == 1) { + --j; + } else { int t = nums[i]; nums[i] = nums[j]; nums[j] = t; - --j; - } else { ++i; + --j; } } return nums; @@ -71,57 +89,21 @@ class Solution { } ``` -### **JavaScript** - -```js -/** - * @param {number[]} nums - * @return {number[]} - */ -var sortArrayByParity = function (nums) { - for (let i = 0, j = nums.length - 1; i < j; ) { - if (nums[i] & 1) { - [nums[i], nums[j]] = [nums[j], nums[i]]; - --j; - } else { - ++i; - } - } - return nums; -}; -``` - -### **Rust** - -```rust -impl Solution { - pub fn sort_array_by_parity(mut nums: Vec) -> Vec { - let (mut l, mut r) = (0, nums.len() - 1); - while l < r { - while l < r && (nums[l] & 1) == 0 { - l += 1; - } - while l < r && (nums[r] & 1) == 1 { - r -= 1; - } - nums.swap(l, r); - } - nums - } -} -``` - ### **C++** ```cpp class Solution { public: vector sortArrayByParity(vector& nums) { - for (int i = 0, j = nums.size() - 1; i < j;) { - if (nums[i] & 1) - swap(nums[i], nums[j--]); - else + int i = 0, j = nums.size() - 1; + while (i < j) { + if (nums[i] % 2 == 0) { ++i; + } else if (nums[j] % 2 == 1) { + --j; + } else { + swap(nums[i++], nums[j--]); + } } return nums; } @@ -133,17 +115,82 @@ public: ```go func sortArrayByParity(nums []int) []int { for i, j := 0, len(nums)-1; i < j; { - if nums[i]%2 == 1 { - nums[i], nums[j] = nums[j], nums[i] + if nums[i]%2 == 0 { + i++ + } else if nums[j]%2 == 1 { j-- } else { - i++ + nums[i], nums[j] = nums[j], nums[i] } } return nums } ``` +### **Rust** + +```rust +impl Solution { + pub fn sort_array_by_parity(mut nums: Vec) -> Vec { + let (mut i, mut j) = (0, nums.len() - 1); + while i < j { + if nums[i] % 2 == 0 { + i += 1; + } else if nums[j] % 2 == 1 { + j -= 1; + } else { + nums.swap(i, j); + i += 1; + j -= 1; + } + } + nums + } +} +``` + +### **TypeScript** + +```ts +function sortArrayByParity(nums: number[]): number[] { + for (let i = 0, j = nums.length - 1; i < j; ) { + if (nums[i] % 2 === 0) { + ++i; + } else if (nums[j] % 2 === 1) { + --j; + } else { + [nums[i], nums[j]] = [nums[j], nums[i]]; + ++i; + --j; + } + } + return nums; +} +``` + +### **JavaScript** + +```js +/** + * @param {number[]} nums + * @return {number[]} + */ +var sortArrayByParity = function (nums) { + for (let i = 0, j = nums.length - 1; i < j; ) { + if (nums[i] % 2 === 0) { + ++i; + } else if (nums[j] % 2 === 1) { + --j; + } else { + [nums[i], nums[j]] = [nums[j], nums[i]]; + ++i; + --j; + } + } + return nums; +}; +``` + ### **...** ``` diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.cpp b/solution/0900-0999/0905.Sort Array By Parity/Solution.cpp index 4bc09afec3b3c..5ad1948aa54e1 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/Solution.cpp +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.cpp @@ -1,12 +1,16 @@ -class Solution { -public: - vector sortArrayByParity(vector& nums) { - for (int i = 0, j = nums.size() - 1; i < j;) { - if (nums[i] & 1) - swap(nums[i], nums[j--]); - else - ++i; - } - return nums; - } +class Solution { +public: + vector sortArrayByParity(vector& nums) { + int i = 0, j = nums.size() - 1; + while (i < j) { + if (nums[i] % 2 == 0) { + ++i; + } else if (nums[j] % 2 == 1) { + --j; + } else { + swap(nums[i++], nums[j--]); + } + } + return nums; + } }; \ No newline at end of file diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.go b/solution/0900-0999/0905.Sort Array By Parity/Solution.go index 7a47f8d7e3a32..8ec75bfc5086a 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/Solution.go +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.go @@ -1,10 +1,11 @@ func sortArrayByParity(nums []int) []int { for i, j := 0, len(nums)-1; i < j; { - if nums[i]%2 == 1 { - nums[i], nums[j] = nums[j], nums[i] + if nums[i]%2 == 0 { + i++ + } else if nums[j]%2 == 1 { j-- } else { - i++ + nums[i], nums[j] = nums[j], nums[i] } } return nums diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.java b/solution/0900-0999/0905.Sort Array By Parity/Solution.java index 3eb59fd0ee9d6..9b49ca6dcfec0 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/Solution.java +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.java @@ -1,15 +1,19 @@ -class Solution { - public int[] sortArrayByParity(int[] nums) { - for (int i = 0, j = nums.length - 1; i < j;) { - if (nums[i] % 2 == 1) { - int t = nums[i]; - nums[i] = nums[j]; - nums[j] = t; - --j; - } else { - ++i; - } - } - return nums; - } +class Solution { + public int[] sortArrayByParity(int[] nums) { + int i = 0, j = nums.length - 1; + while (i < j) { + if (nums[i] % 2 == 0) { + ++i; + } else if (nums[j] % 2 == 1) { + --j; + } else { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; + ++i; + --j; + } + } + return nums; + } } \ No newline at end of file diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.js b/solution/0900-0999/0905.Sort Array By Parity/Solution.js index 9fd9bb2b16123..33e22535babf2 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/Solution.js +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.js @@ -4,11 +4,14 @@ */ var sortArrayByParity = function (nums) { for (let i = 0, j = nums.length - 1; i < j; ) { - if (nums[i] & 1) { - [nums[i], nums[j]] = [nums[j], nums[i]]; + if (nums[i] % 2 === 0) { + ++i; + } else if (nums[j] % 2 === 1) { --j; } else { + [nums[i], nums[j]] = [nums[j], nums[i]]; ++i; + --j; } } return nums; diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.py b/solution/0900-0999/0905.Sort Array By Parity/Solution.py index 52c5fbefdbd8b..5d425faa7e838 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/Solution.py +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.py @@ -1,10 +1,12 @@ -class Solution: - def sortArrayByParity(self, nums: List[int]) -> List[int]: - i, j = 0, len(nums) - 1 - while i < j: - if nums[i] & 1: - nums[i], nums[j] = nums[j], nums[i] - j -= 1 - else: - i += 1 - return nums +class Solution: + def sortArrayByParity(self, nums: List[int]) -> List[int]: + i, j = 0, len(nums) - 1 + while i < j: + if nums[i] % 2 == 0: + i += 1 + elif nums[j] % 2 == 1: + j -= 1 + else: + nums[i], nums[j] = nums[j], nums[i] + i, j = i + 1, j - 1 + return nums diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.rs b/solution/0900-0999/0905.Sort Array By Parity/Solution.rs index 9e4f92e97071c..680c80c6e0cd4 100644 --- a/solution/0900-0999/0905.Sort Array By Parity/Solution.rs +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.rs @@ -1,14 +1,16 @@ impl Solution { pub fn sort_array_by_parity(mut nums: Vec) -> Vec { - let (mut l, mut r) = (0, nums.len() - 1); - while l < r { - while l < r && (nums[l] & 1) == 0 { - l += 1; + let (mut i, mut j) = (0, nums.len() - 1); + while i < j { + if nums[i] % 2 == 0 { + i += 1; + } else if nums[j] % 2 == 1 { + j -= 1; + } else { + nums.swap(i, j); + i += 1; + j -= 1; } - while l < r && (nums[r] & 1) == 1 { - r -= 1; - } - nums.swap(l, r); } nums } diff --git a/solution/0900-0999/0905.Sort Array By Parity/Solution.ts b/solution/0900-0999/0905.Sort Array By Parity/Solution.ts new file mode 100644 index 0000000000000..40a61491bd62e --- /dev/null +++ b/solution/0900-0999/0905.Sort Array By Parity/Solution.ts @@ -0,0 +1,14 @@ +function sortArrayByParity(nums: number[]): number[] { + for (let i = 0, j = nums.length - 1; i < j; ) { + if (nums[i] % 2 === 0) { + ++i; + } else if (nums[j] % 2 === 1) { + --j; + } else { + [nums[i], nums[j]] = [nums[j], nums[i]]; + ++i; + --j; + } + } + return nums; +} diff --git a/solution/0900-0999/0908.Smallest Range I/README.md b/solution/0900-0999/0908.Smallest Range I/README.md index 4fa95a35821c2..dbf604ee77ce9 100644 --- a/solution/0900-0999/0908.Smallest Range I/README.md +++ b/solution/0900-0999/0908.Smallest Range I/README.md @@ -91,9 +91,8 @@ class Solution { class Solution { public: int smallestRangeI(vector& nums, int k) { - int mx = *max_element(nums.begin(), nums.end()); - int mi = *min_element(nums.begin(), nums.end()); - return max(0, mx - mi - k * 2); + auto [mi, mx] = minmax_element(nums.begin(), nums.end()); + return max(0, *mx - *mi - k * 2); } }; ``` diff --git a/solution/0900-0999/0908.Smallest Range I/README_EN.md b/solution/0900-0999/0908.Smallest Range I/README_EN.md index be5654f3d5e49..87953cda8851f 100644 --- a/solution/0900-0999/0908.Smallest Range I/README_EN.md +++ b/solution/0900-0999/0908.Smallest Range I/README_EN.md @@ -81,9 +81,8 @@ class Solution { class Solution { public: int smallestRangeI(vector& nums, int k) { - int mx = *max_element(nums.begin(), nums.end()); - int mi = *min_element(nums.begin(), nums.end()); - return max(0, mx - mi - k * 2); + auto [mi, mx] = minmax_element(nums.begin(), nums.end()); + return max(0, *mx - *mi - k * 2); } }; ``` diff --git a/solution/0900-0999/0908.Smallest Range I/Solution.cpp b/solution/0900-0999/0908.Smallest Range I/Solution.cpp index ac139a53b730b..7be5ca1f19eec 100644 --- a/solution/0900-0999/0908.Smallest Range I/Solution.cpp +++ b/solution/0900-0999/0908.Smallest Range I/Solution.cpp @@ -1,8 +1,7 @@ -class Solution { -public: - int smallestRangeI(vector& nums, int k) { - int mx = *max_element(nums.begin(), nums.end()); - int mi = *min_element(nums.begin(), nums.end()); - return max(0, mx - mi - k * 2); - } +class Solution { +public: + int smallestRangeI(vector& nums, int k) { + auto [mi, mx] = minmax_element(nums.begin(), nums.end()); + return max(0, *mx - *mi - k * 2); + } }; \ No newline at end of file