From 13efd07084a28237315318af4e4eeac75e183c8d Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 16 Dec 2023 20:08:56 +0800 Subject: [PATCH 1/3] feat: add solutions to lc problems: No.0899~0908 * 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..3ea0141592c3f 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..78e04ab257f93 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 From c58b35549aa1628c8482c4beb9c6211615a19327 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 16 Dec 2023 20:13:20 +0800 Subject: [PATCH 2/3] fix: cpp code --- solution/0900-0999/0900.RLE Iterator/Solution.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.cpp b/solution/0900-0999/0900.RLE Iterator/Solution.cpp index 3ea0141592c3f..55f97fd09bde5 100644 --- a/solution/0900-0999/0900.RLE Iterator/Solution.cpp +++ b/solution/0900-0999/0900.RLE Iterator/Solution.cpp @@ -3,7 +3,7 @@ class RLEIterator { RLEIterator(vector& encoding) { this->encoding = encoding; } - + int next(int n) { while (i < encoding.size()) { if (encoding[i] - j < n) { From 5c7da6fb55d1d7b2f14006cf2212995188e372f1 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 16 Dec 2023 20:16:06 +0800 Subject: [PATCH 3/3] fix: java code --- solution/0900-0999/0900.RLE Iterator/Solution.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solution/0900-0999/0900.RLE Iterator/Solution.java b/solution/0900-0999/0900.RLE Iterator/Solution.java index 78e04ab257f93..94f0ad4d82376 100644 --- a/solution/0900-0999/0900.RLE Iterator/Solution.java +++ b/solution/0900-0999/0900.RLE Iterator/Solution.java @@ -6,7 +6,7 @@ class RLEIterator { public RLEIterator(int[] encoding) { this.encoding = encoding; } - + public int next(int n) { while (i < encoding.length) { if (encoding[i] - j < n) {