From 8b3600b3d7f7de1e671e54782aabf85bb679684b Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 25 Oct 2023 19:08:25 +0800 Subject: [PATCH] feat: add solutions to lc problems: No.1215,1216 * No.1215.Stepping Numbers * No.1216.Valid Palindrome III --- .../1200-1299/1215.Stepping Numbers/README.md | 64 +++++++++++++++-- .../1215.Stepping Numbers/README_EN.md | 66 +++++++++++++++-- .../1215.Stepping Numbers/Solution.cpp | 48 ++++++++----- .../1215.Stepping Numbers/Solution.ts | 27 +++++++ .../1216.Valid Palindrome III/README.md | 57 +++++++++++++++ .../1216.Valid Palindrome III/README_EN.md | 71 +++++++++++++++++++ .../1216.Valid Palindrome III/Solution.rs | 27 +++++++ .../1216.Valid Palindrome III/Solution.ts | 20 ++++++ 8 files changed, 348 insertions(+), 32 deletions(-) create mode 100644 solution/1200-1299/1215.Stepping Numbers/Solution.ts create mode 100644 solution/1200-1299/1216.Valid Palindrome III/Solution.rs create mode 100644 solution/1200-1299/1216.Valid Palindrome III/Solution.ts diff --git a/solution/1200-1299/1215.Stepping Numbers/README.md b/solution/1200-1299/1215.Stepping Numbers/README.md index e21e04cf1621d..9285edc87edcb 100644 --- a/solution/1200-1299/1215.Stepping Numbers/README.md +++ b/solution/1200-1299/1215.Stepping Numbers/README.md @@ -34,6 +34,12 @@ **方法一:BFS** +首先,如果 $low$ 为 $0$,那么我们需要将 $0$ 加入答案中。 + +接下来,我们创建一个队列 $q$,并将 $1 \sim 9$ 加入队列中。然后我们不断从队列中取出元素,记当前元素为 $v$,如果 $v$ 大于 $high$,那么我们就停止搜索;如果 $v$ 在 $[low, high]$ 的范围内,那么我们将 $v$ 加入答案中。然后,我们需要将 $v$ 的最后一位数字记为 $x$,如果 $x \gt 0$,那么我们将 $v \times 10 + x - 1$ 加入队列中;如果 $x \lt 9$,那么我们将 $v \times 10 + x + 1$ 加入队列中。重复上述操作,直到队列为空。 + +时间复杂度 $O(10 \times 2^{\log M})$,空间复杂度 $O(2^{\log M})$,其中 $M$ 为 $high$ 的位数。 + ### **Python3** @@ -104,17 +110,29 @@ class Solution { public: vector countSteppingNumbers(int low, int high) { vector ans; - if (low == 0) ans.push_back(0); + if (low == 0) { + ans.push_back(0); + } queue q; - for (int i = 1; i < 10; ++i) q.push(i); + for (int i = 1; i < 10; ++i) { + q.push(i); + } while (!q.empty()) { - int v = q.front(); + long long v = q.front(); q.pop(); - if (v > high) break; - if (v >= low) ans.push_back(v); + if (v > high) { + break; + } + if (v >= low) { + ans.push_back(v); + } int x = v % 10; - if (x) q.push(1ll * v * 10 + x - 1); - if (x < 9) q.push(1ll * v * 10 + x + 1); + if (x > 0) { + q.push(v * 10 + x - 1); + } + if (x < 9) { + q.push(v * 10 + x + 1); + } } return ans; } @@ -151,6 +169,38 @@ func countSteppingNumbers(low int, high int) []int { } ``` +### **TypeScript** + +```ts +function countSteppingNumbers(low: number, high: number): number[] { + const ans: number[] = []; + if (low === 0) { + ans.push(0); + } + const q: number[] = []; + for (let i = 1; i < 10; ++i) { + q.push(i); + } + while (q.length) { + const v = q.shift()!; + if (v > high) { + break; + } + if (v >= low) { + ans.push(v); + } + const x = v % 10; + if (x > 0) { + q.push(v * 10 + x - 1); + } + if (x < 9) { + q.push(v * 10 + x + 1); + } + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1200-1299/1215.Stepping Numbers/README_EN.md b/solution/1200-1299/1215.Stepping Numbers/README_EN.md index a2e98392744cc..d51716dc39329 100644 --- a/solution/1200-1299/1215.Stepping Numbers/README_EN.md +++ b/solution/1200-1299/1215.Stepping Numbers/README_EN.md @@ -36,6 +36,14 @@ ## Solutions +**Solution 1: BFS** + +First, if $low$ is $0$, we need to add $0$ to the answer. + +Next, we create a queue $q$ and add $1 \sim 9$ to the queue. Then, we repeatedly take out elements from the queue. Let the current element be $v$. If $v$ is greater than $high$, we stop searching. If $v$ is in the range $[low, high]$, we add $v$ to the answer. Then, we need to record the last digit of $v$ as $x$. If $x \gt 0$, we add $v \times 10 + x - 1$ to the queue. If $x \lt 9$, we add $v \times 10 + x + 1$ to the queue. Repeat the above steps until the queue is empty. + +The time complexity is $O(10 \times 2^{\log M})$, and the space complexity is $O(2^{\log M})$, where $M$ is the number of digits in $high$. + ### **Python3** @@ -102,17 +110,29 @@ class Solution { public: vector countSteppingNumbers(int low, int high) { vector ans; - if (low == 0) ans.push_back(0); + if (low == 0) { + ans.push_back(0); + } queue q; - for (int i = 1; i < 10; ++i) q.push(i); + for (int i = 1; i < 10; ++i) { + q.push(i); + } while (!q.empty()) { - int v = q.front(); + long long v = q.front(); q.pop(); - if (v > high) break; - if (v >= low) ans.push_back(v); + if (v > high) { + break; + } + if (v >= low) { + ans.push_back(v); + } int x = v % 10; - if (x) q.push(1ll * v * 10 + x - 1); - if (x < 9) q.push(1ll * v * 10 + x + 1); + if (x > 0) { + q.push(v * 10 + x - 1); + } + if (x < 9) { + q.push(v * 10 + x + 1); + } } return ans; } @@ -149,6 +169,38 @@ func countSteppingNumbers(low int, high int) []int { } ``` +### **TypeScript** + +```ts +function countSteppingNumbers(low: number, high: number): number[] { + const ans: number[] = []; + if (low === 0) { + ans.push(0); + } + const q: number[] = []; + for (let i = 1; i < 10; ++i) { + q.push(i); + } + while (q.length) { + const v = q.shift()!; + if (v > high) { + break; + } + if (v >= low) { + ans.push(v); + } + const x = v % 10; + if (x > 0) { + q.push(v * 10 + x - 1); + } + if (x < 9) { + q.push(v * 10 + x + 1); + } + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1200-1299/1215.Stepping Numbers/Solution.cpp b/solution/1200-1299/1215.Stepping Numbers/Solution.cpp index c847744f1743a..66a18172067ba 100644 --- a/solution/1200-1299/1215.Stepping Numbers/Solution.cpp +++ b/solution/1200-1299/1215.Stepping Numbers/Solution.cpp @@ -1,19 +1,31 @@ -class Solution { -public: - vector countSteppingNumbers(int low, int high) { - vector ans; - if (low == 0) ans.push_back(0); - queue q; - for (int i = 1; i < 10; ++i) q.push(i); - while (!q.empty()) { - int v = q.front(); - q.pop(); - if (v > high) break; - if (v >= low) ans.push_back(v); - int x = v % 10; - if (x) q.push(1ll * v * 10 + x - 1); - if (x < 9) q.push(1ll * v * 10 + x + 1); - } - return ans; - } +class Solution { +public: + vector countSteppingNumbers(int low, int high) { + vector ans; + if (low == 0) { + ans.push_back(0); + } + queue q; + for (int i = 1; i < 10; ++i) { + q.push(i); + } + while (!q.empty()) { + long long v = q.front(); + q.pop(); + if (v > high) { + break; + } + if (v >= low) { + ans.push_back(v); + } + int x = v % 10; + if (x > 0) { + q.push(v * 10 + x - 1); + } + if (x < 9) { + q.push(v * 10 + x + 1); + } + } + return ans; + } }; \ No newline at end of file diff --git a/solution/1200-1299/1215.Stepping Numbers/Solution.ts b/solution/1200-1299/1215.Stepping Numbers/Solution.ts new file mode 100644 index 0000000000000..342d02de71d55 --- /dev/null +++ b/solution/1200-1299/1215.Stepping Numbers/Solution.ts @@ -0,0 +1,27 @@ +function countSteppingNumbers(low: number, high: number): number[] { + const ans: number[] = []; + if (low === 0) { + ans.push(0); + } + const q: number[] = []; + for (let i = 1; i < 10; ++i) { + q.push(i); + } + while (q.length) { + const v = q.shift()!; + if (v > high) { + break; + } + if (v >= low) { + ans.push(v); + } + const x = v % 10; + if (x > 0) { + q.push(v * 10 + x - 1); + } + if (x < 9) { + q.push(v * 10 + x + 1); + } + } + return ans; +} diff --git a/solution/1200-1299/1216.Valid Palindrome III/README.md b/solution/1200-1299/1216.Valid Palindrome III/README.md index dacad8a34376c..14140d4871aaf 100644 --- a/solution/1200-1299/1216.Valid Palindrome III/README.md +++ b/solution/1200-1299/1216.Valid Palindrome III/README.md @@ -170,6 +170,63 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function isValidPalindrome(s: string, k: number): boolean { + const n = s.length; + const f: number[][] = Array.from({ length: n }, () => Array.from({ length: n }, () => 0)); + for (let i = 0; i < n; ++i) { + f[i][i] = 1; + } + for (let i = n - 2; ~i; --i) { + for (let j = i + 1; j < n; ++j) { + if (s[i] === s[j]) { + f[i][j] = f[i + 1][j - 1] + 2; + } else { + f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]); + } + if (f[i][j] + k >= n) { + return true; + } + } + } + return false; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn is_valid_palindrome(s: String, k: i32) -> bool { + let s = s.as_bytes(); + let n = s.len(); + let mut f = vec![vec![0; n]; n]; + + for i in 0..n { + f[i][i] = 1; + } + + for i in (0..n - 2).rev() { + for j in (i + 1)..n { + if s[i] == s[j] { + f[i][j] = f[i + 1][j - 1] + 2; + } else { + f[i][j] = std::cmp::max(f[i + 1][j], f[i][j - 1]); + } + + if f[i][j] + k >= n as i32 { + return true; + } + } + } + + false + } +} +``` + ### **...** ``` diff --git a/solution/1200-1299/1216.Valid Palindrome III/README_EN.md b/solution/1200-1299/1216.Valid Palindrome III/README_EN.md index 6be6a7feeac12..2e0786a1b09f2 100644 --- a/solution/1200-1299/1216.Valid Palindrome III/README_EN.md +++ b/solution/1200-1299/1216.Valid Palindrome III/README_EN.md @@ -35,6 +35,20 @@ ## Solutions +**Solution 1: Dynamic Programming** + +The problem requires us to remove at most $k$ characters to make the remaining string a palindrome. This can be transformed into finding the longest palindromic subsequence. + +We define $f[i][j]$ as the length of the longest palindromic subsequence in the substring $s[i..j]$. Initially, we have $f[i][i] = 1$ for all $i$, since each single character is a palindrome. + +If $s[i] = s[j]$, then we have $f[i][j] = f[i+1][j-1] + 2$, since we can add both $s[i]$ and $s[j]$ to the longest palindromic subsequence of $s[i+1..j-1]$. + +If $s[i] \neq s[j]$, then we have $f[i][j] = \max(f[i+1][j], f[i][j-1])$, since we need to remove either $s[i]$ or $s[j]$ to make the remaining substring a palindrome. + +Finally, we check whether there exists $f[i][j] + k \geq n$, where $n$ is the length of the string $s$. If so, it means that we can remove at most $k$ characters to make the remaining string a palindrome. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the string $s$. + ### **Python3** @@ -146,6 +160,63 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function isValidPalindrome(s: string, k: number): boolean { + const n = s.length; + const f: number[][] = Array.from({ length: n }, () => Array.from({ length: n }, () => 0)); + for (let i = 0; i < n; ++i) { + f[i][i] = 1; + } + for (let i = n - 2; ~i; --i) { + for (let j = i + 1; j < n; ++j) { + if (s[i] === s[j]) { + f[i][j] = f[i + 1][j - 1] + 2; + } else { + f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]); + } + if (f[i][j] + k >= n) { + return true; + } + } + } + return false; +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn is_valid_palindrome(s: String, k: i32) -> bool { + let s = s.as_bytes(); + let n = s.len(); + let mut f = vec![vec![0; n]; n]; + + for i in 0..n { + f[i][i] = 1; + } + + for i in (0..n - 2).rev() { + for j in (i + 1)..n { + if s[i] == s[j] { + f[i][j] = f[i + 1][j - 1] + 2; + } else { + f[i][j] = std::cmp::max(f[i + 1][j], f[i][j - 1]); + } + + if f[i][j] + k >= n as i32 { + return true; + } + } + } + + false + } +} +``` + ### **...** ``` diff --git a/solution/1200-1299/1216.Valid Palindrome III/Solution.rs b/solution/1200-1299/1216.Valid Palindrome III/Solution.rs new file mode 100644 index 0000000000000..af19672b75485 --- /dev/null +++ b/solution/1200-1299/1216.Valid Palindrome III/Solution.rs @@ -0,0 +1,27 @@ +impl Solution { + pub fn is_valid_palindrome(s: String, k: i32) -> bool { + let s = s.as_bytes(); + let n = s.len(); + let mut f = vec![vec![0; n]; n]; + + for i in 0..n { + f[i][i] = 1; + } + + for i in (0..n - 2).rev() { + for j in (i + 1)..n { + if s[i] == s[j] { + f[i][j] = f[i + 1][j - 1] + 2; + } else { + f[i][j] = std::cmp::max(f[i + 1][j], f[i][j - 1]); + } + + if f[i][j] + k >= n as i32 { + return true; + } + } + } + + false + } +} \ No newline at end of file diff --git a/solution/1200-1299/1216.Valid Palindrome III/Solution.ts b/solution/1200-1299/1216.Valid Palindrome III/Solution.ts new file mode 100644 index 0000000000000..a89cc7017c845 --- /dev/null +++ b/solution/1200-1299/1216.Valid Palindrome III/Solution.ts @@ -0,0 +1,20 @@ +function isValidPalindrome(s: string, k: number): boolean { + const n = s.length; + const f: number[][] = Array.from({ length: n }, () => Array.from({ length: n }, () => 0)); + for (let i = 0; i < n; ++i) { + f[i][i] = 1; + } + for (let i = n - 2; ~i; --i) { + for (let j = i + 1; j < n; ++j) { + if (s[i] === s[j]) { + f[i][j] = f[i + 1][j - 1] + 2; + } else { + f[i][j] = Math.max(f[i + 1][j], f[i][j - 1]); + } + if (f[i][j] + k >= n) { + return true; + } + } + } + return false; +}