From af21d5d8c2a784f2b5c354536b7859199f7ebdbf Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 23 Oct 2024 09:18:21 +0800 Subject: [PATCH 1/2] feat: add solutions to lc problems: No.3314~3316 * No.3314.Construct the Minimum Bitwise Array I * No.3315.Construct the Minimum Bitwise Array II * No.3316.Find Maximum Removals From Source String --- .../README.md | 99 +++++++++++++- .../README_EN.md | 99 +++++++++++++- .../Solution.cpp | 19 +++ .../Solution.go | 15 ++ .../Solution.java | 20 +++ .../Solution.py | 12 ++ .../Solution.ts | 16 +++ .../README.md | 99 +++++++++++++- .../README_EN.md | 99 +++++++++++++- .../Solution.cpp | 19 +++ .../Solution.go | 15 ++ .../Solution.java | 20 +++ .../Solution.py | 12 ++ .../Solution.ts | 16 +++ .../README.md | 129 +++++++++++++++++- .../README_EN.md | 129 +++++++++++++++++- .../Solution.cpp | 24 ++++ .../Solution.go | 27 ++++ .../Solution.java | 24 ++++ .../Solution.py | 12 ++ .../Solution.ts | 22 +++ 21 files changed, 903 insertions(+), 24 deletions(-) create mode 100644 solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.cpp create mode 100644 solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.go create mode 100644 solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.java create mode 100644 solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.py create mode 100644 solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.ts create mode 100644 solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.cpp create mode 100644 solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.go create mode 100644 solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.java create mode 100644 solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.py create mode 100644 solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.ts create mode 100644 solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.cpp create mode 100644 solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.go create mode 100644 solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java create mode 100644 solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.py create mode 100644 solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.ts diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README.md b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README.md index fea3aaaafc814..017f4a2fae88d 100644 --- a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README.md +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README.md @@ -80,32 +80,123 @@ tags: -### 方法一 +### 方法一:位运算 + +对于一个整数 $a$,满足 $a \lor (a + 1)$ 的结果一定为奇数,因此,如果 $\text{nums[i]}$ 是偶数,那么 $\text{ans}[i]$ 一定不存在,直接返回 $-1$。本题中 $\textit{nums}[i]$ 是质数,判断是否是偶数,只需要判断是否等于 $2$ 即可。 + +如果 $\text{nums[i]}$ 是奇数,假设 $\text{nums[i]} = \text{0b1101101}$,由于 $a \lor (a + 1) = \text{nums[i]}$,等价于将 $a$ 的最后一个为 $0$ 的二进制位变为 $1$。那么求解 $a$,就等价于将 $\text{nums[i]}$ 的最后一个 $0$ 的下一位 $1$ 变为 $0$。我们只需要从低位(下标为 $1$)开始遍历,找到第一个为 $0$ 的二进制位,如果是第 $i$ 位,那么我们就将 $\text{nums[i]}$ 的第 $i - 1$ 位变为 $1$,即 $\text{ans}[i] = \text{nums[i]} \oplus 2^{i - 1}$。 + +遍历所有的 $\text{nums[i]}$,即可得到答案。 + +时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别是数组 $\text{nums}$ 的长度和数组中的最大值。忽略答案数组的空间消耗,空间复杂度 $O(1)$。 #### Python3 ```python - +class Solution: + def minBitwiseArray(self, nums: List[int]) -> List[int]: + ans = [] + for x in nums: + if x == 2: + ans.append(-1) + else: + for i in range(1, 32): + if x >> i & 1 ^ 1: + ans.append(x ^ 1 << (i - 1)) + break + return ans ``` #### Java ```java - +class Solution { + public int[] minBitwiseArray(List nums) { + int n = nums.size(); + int[] ans = new int[n]; + for (int i = 0; i < n; ++i) { + int x = nums.get(i); + if (x == 2) { + ans[i] = -1; + } else { + for (int j = 1; j < 32; ++j) { + if ((x >> j & 1) == 0) { + ans[i] = x ^ 1 << (j - 1); + break; + } + } + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector minBitwiseArray(vector& nums) { + vector ans; + for (int x : nums) { + if (x == 2) { + ans.push_back(-1); + } else { + for (int i = 1; i < 32; ++i) { + if (x >> i & 1 ^ 1) { + ans.push_back(x ^ 1 << (i - 1)); + break; + } + } + } + } + return ans; + } +}; ``` #### Go ```go +func minBitwiseArray(nums []int) (ans []int) { + for _, x := range nums { + if x == 2 { + ans = append(ans, -1) + } else { + for i := 1; i < 32; i++ { + if x>>i&1 == 0 { + ans = append(ans, x^1<<(i-1)) + break + } + } + } + } + return +} +``` +#### TypeScript + +```ts +function minBitwiseArray(nums: number[]): number[] { + const ans: number[] = []; + for (const x of nums) { + if (x === 2) { + ans.push(-1); + } else { + for (let i = 1; i < 32; ++i) { + if (((x >> i) & 1) ^ 1) { + ans.push(x ^ (1 << (i - 1))); + break; + } + } + } + } + return ans; +} ``` diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md index c133b365167c9..e2c4536d7f2fd 100644 --- a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/README_EN.md @@ -74,32 +74,123 @@ tags: -### Solution 1 +### Solution 1: Bit Manipulation + +For an integer $a$, the result of $a \lor (a + 1)$ is always odd. Therefore, if $\text{nums[i]}$ is even, then $\text{ans}[i]$ does not exist, and we directly return $-1$. In this problem, $\textit{nums}[i]$ is a prime number, so to check if it is even, we only need to check if it equals $2$. + +If $\text{nums[i]}$ is odd, suppose $\text{nums[i]} = \text{0b1101101}$. Since $a \lor (a + 1) = \text{nums[i]}$, this is equivalent to changing the last $0$ bit of $a$ to $1$. To solve for $a$, we need to change the bit after the last $0$ in $\text{nums[i]}$ to $0$. We start traversing from the least significant bit (index $1$) and find the first $0$ bit. If it is at position $i$, we change the $(i - 1)$-th bit of $\text{nums[i]}$ to $1$, i.e., $\text{ans}[i] = \text{nums[i]} \oplus 2^{i - 1}$. + +By traversing all elements in $\text{nums}$, we can obtain the answer. + +The time complexity is $O(n \times \log M)$, where $n$ and $M$ are the length of the array $\text{nums}$ and the maximum value in the array, respectively. Ignoring the space consumption of the answer array, the space complexity is $O(1)$. #### Python3 ```python - +class Solution: + def minBitwiseArray(self, nums: List[int]) -> List[int]: + ans = [] + for x in nums: + if x == 2: + ans.append(-1) + else: + for i in range(1, 32): + if x >> i & 1 ^ 1: + ans.append(x ^ 1 << (i - 1)) + break + return ans ``` #### Java ```java - +class Solution { + public int[] minBitwiseArray(List nums) { + int n = nums.size(); + int[] ans = new int[n]; + for (int i = 0; i < n; ++i) { + int x = nums.get(i); + if (x == 2) { + ans[i] = -1; + } else { + for (int j = 1; j < 32; ++j) { + if ((x >> j & 1) == 0) { + ans[i] = x ^ 1 << (j - 1); + break; + } + } + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector minBitwiseArray(vector& nums) { + vector ans; + for (int x : nums) { + if (x == 2) { + ans.push_back(-1); + } else { + for (int i = 1; i < 32; ++i) { + if (x >> i & 1 ^ 1) { + ans.push_back(x ^ 1 << (i - 1)); + break; + } + } + } + } + return ans; + } +}; ``` #### Go ```go +func minBitwiseArray(nums []int) (ans []int) { + for _, x := range nums { + if x == 2 { + ans = append(ans, -1) + } else { + for i := 1; i < 32; i++ { + if x>>i&1 == 0 { + ans = append(ans, x^1<<(i-1)) + break + } + } + } + } + return +} +``` +#### TypeScript + +```ts +function minBitwiseArray(nums: number[]): number[] { + const ans: number[] = []; + for (const x of nums) { + if (x === 2) { + ans.push(-1); + } else { + for (let i = 1; i < 32; ++i) { + if (((x >> i) & 1) ^ 1) { + ans.push(x ^ (1 << (i - 1))); + break; + } + } + } + } + return ans; +} ``` diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.cpp b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.cpp new file mode 100644 index 0000000000000..79206f73c2455 --- /dev/null +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + vector minBitwiseArray(vector& nums) { + vector ans; + for (int x : nums) { + if (x == 2) { + ans.push_back(-1); + } else { + for (int i = 1; i < 32; ++i) { + if (x >> i & 1 ^ 1) { + ans.push_back(x ^ 1 << (i - 1)); + break; + } + } + } + } + return ans; + } +}; diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.go b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.go new file mode 100644 index 0000000000000..2f931a4ab1283 --- /dev/null +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.go @@ -0,0 +1,15 @@ +func minBitwiseArray(nums []int) (ans []int) { + for _, x := range nums { + if x == 2 { + ans = append(ans, -1) + } else { + for i := 1; i < 32; i++ { + if x>>i&1 == 0 { + ans = append(ans, x^1<<(i-1)) + break + } + } + } + } + return +} diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.java b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.java new file mode 100644 index 0000000000000..13433ab0347ed --- /dev/null +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.java @@ -0,0 +1,20 @@ +class Solution { + public int[] minBitwiseArray(List nums) { + int n = nums.size(); + int[] ans = new int[n]; + for (int i = 0; i < n; ++i) { + int x = nums.get(i); + if (x == 2) { + ans[i] = -1; + } else { + for (int j = 1; j < 32; ++j) { + if ((x >> j & 1) == 0) { + ans[i] = x ^ 1 << (j - 1); + break; + } + } + } + } + return ans; + } +} diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.py b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.py new file mode 100644 index 0000000000000..82f2609a941ff --- /dev/null +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.py @@ -0,0 +1,12 @@ +class Solution: + def minBitwiseArray(self, nums: List[int]) -> List[int]: + ans = [] + for x in nums: + if x == 2: + ans.append(-1) + else: + for i in range(1, 32): + if x >> i & 1 ^ 1: + ans.append(x ^ 1 << (i - 1)) + break + return ans diff --git a/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.ts b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.ts new file mode 100644 index 0000000000000..db16f08631bca --- /dev/null +++ b/solution/3300-3399/3314.Construct the Minimum Bitwise Array I/Solution.ts @@ -0,0 +1,16 @@ +function minBitwiseArray(nums: number[]): number[] { + const ans: number[] = []; + for (const x of nums) { + if (x === 2) { + ans.push(-1); + } else { + for (let i = 1; i < 32; ++i) { + if (((x >> i) & 1) ^ 1) { + ans.push(x ^ (1 << (i - 1))); + break; + } + } + } + } + return ans; +} diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README.md b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README.md index 1fffa7ba785e1..02dae50a9bd9c 100644 --- a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README.md +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README.md @@ -80,32 +80,123 @@ tags: -### 方法一 +### 方法一:位运算 + +对于一个整数 $a$,满足 $a \lor (a + 1)$ 的结果一定为奇数,因此,如果 $\text{nums[i]}$ 是偶数,那么 $\text{ans}[i]$ 一定不存在,直接返回 $-1$。本题中 $\textit{nums}[i]$ 是质数,判断是否是偶数,只需要判断是否等于 $2$ 即可。 + +如果 $\text{nums[i]}$ 是奇数,假设 $\text{nums[i]} = \text{0b1101101}$,由于 $a \lor (a + 1) = \text{nums[i]}$,等价于将 $a$ 的最后一个为 $0$ 的二进制位变为 $1$。那么求解 $a$,就等价于将 $\text{nums[i]}$ 的最后一个 $0$ 的下一位 $1$ 变为 $0$。我们只需要从低位(下标为 $1$)开始遍历,找到第一个为 $0$ 的二进制位,如果是第 $i$ 位,那么我们就将 $\text{nums[i]}$ 的第 $i - 1$ 位变为 $1$,即 $\text{ans}[i] = \text{nums[i]} \oplus 2^{i - 1}$。 + +遍历所有的 $\text{nums[i]}$,即可得到答案。 + +时间复杂度 $O(n \times \log M)$,其中 $n$ 和 $M$ 分别是数组 $\text{nums}$ 的长度和数组中的最大值。忽略答案数组的空间消耗,空间复杂度 $O(1)$。 #### Python3 ```python - +class Solution: + def minBitwiseArray(self, nums: List[int]) -> List[int]: + ans = [] + for x in nums: + if x == 2: + ans.append(-1) + else: + for i in range(1, 32): + if x >> i & 1 ^ 1: + ans.append(x ^ 1 << (i - 1)) + break + return ans ``` #### Java ```java - +class Solution { + public int[] minBitwiseArray(List nums) { + int n = nums.size(); + int[] ans = new int[n]; + for (int i = 0; i < n; ++i) { + int x = nums.get(i); + if (x == 2) { + ans[i] = -1; + } else { + for (int j = 1; j < 32; ++j) { + if ((x >> j & 1) == 0) { + ans[i] = x ^ 1 << (j - 1); + break; + } + } + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector minBitwiseArray(vector& nums) { + vector ans; + for (int x : nums) { + if (x == 2) { + ans.push_back(-1); + } else { + for (int i = 1; i < 32; ++i) { + if (x >> i & 1 ^ 1) { + ans.push_back(x ^ 1 << (i - 1)); + break; + } + } + } + } + return ans; + } +}; ``` #### Go ```go +func minBitwiseArray(nums []int) (ans []int) { + for _, x := range nums { + if x == 2 { + ans = append(ans, -1) + } else { + for i := 1; i < 32; i++ { + if x>>i&1 == 0 { + ans = append(ans, x^1<<(i-1)) + break + } + } + } + } + return +} +``` +#### TypeScript + +```ts +function minBitwiseArray(nums: number[]): number[] { + const ans: number[] = []; + for (const x of nums) { + if (x === 2) { + ans.push(-1); + } else { + for (let i = 1; i < 32; ++i) { + if (((x >> i) & 1) ^ 1) { + ans.push(x ^ (1 << (i - 1))); + break; + } + } + } + } + return ans; +} ``` diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md index da4aa0cd7cce0..d24fe77a17264 100644 --- a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/README_EN.md @@ -74,32 +74,123 @@ tags: -### Solution 1 +### Solution 1: Bit Manipulation + +For an integer $a$, the result of $a \lor (a + 1)$ is always odd. Therefore, if $\text{nums[i]}$ is even, then $\text{ans}[i]$ does not exist, and we directly return $-1$. In this problem, $\textit{nums}[i]$ is a prime number, so to check if it is even, we only need to check if it equals $2$. + +If $\text{nums[i]}$ is odd, suppose $\text{nums[i]} = \text{0b1101101}$. Since $a \lor (a + 1) = \text{nums[i]}$, this is equivalent to changing the last $0$ bit of $a$ to $1$. To solve for $a$, we need to change the bit after the last $0$ in $\text{nums[i]}$ to $0$. We start traversing from the least significant bit (index $1$) and find the first $0$ bit. If it is at position $i$, we change the $(i - 1)$-th bit of $\text{nums[i]}$ to $1$, i.e., $\text{ans}[i] = \text{nums[i]} \oplus 2^{i - 1}$. + +By traversing all elements in $\text{nums}$, we can obtain the answer. + +The time complexity is $O(n \times \log M)$, where $n$ and $M$ are the length of the array $\text{nums}$ and the maximum value in the array, respectively. Ignoring the space consumption of the answer array, the space complexity is $O(1)$. #### Python3 ```python - +class Solution: + def minBitwiseArray(self, nums: List[int]) -> List[int]: + ans = [] + for x in nums: + if x == 2: + ans.append(-1) + else: + for i in range(1, 32): + if x >> i & 1 ^ 1: + ans.append(x ^ 1 << (i - 1)) + break + return ans ``` #### Java ```java - +class Solution { + public int[] minBitwiseArray(List nums) { + int n = nums.size(); + int[] ans = new int[n]; + for (int i = 0; i < n; ++i) { + int x = nums.get(i); + if (x == 2) { + ans[i] = -1; + } else { + for (int j = 1; j < 32; ++j) { + if ((x >> j & 1) == 0) { + ans[i] = x ^ 1 << (j - 1); + break; + } + } + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + vector minBitwiseArray(vector& nums) { + vector ans; + for (int x : nums) { + if (x == 2) { + ans.push_back(-1); + } else { + for (int i = 1; i < 32; ++i) { + if (x >> i & 1 ^ 1) { + ans.push_back(x ^ 1 << (i - 1)); + break; + } + } + } + } + return ans; + } +}; ``` #### Go ```go +func minBitwiseArray(nums []int) (ans []int) { + for _, x := range nums { + if x == 2 { + ans = append(ans, -1) + } else { + for i := 1; i < 32; i++ { + if x>>i&1 == 0 { + ans = append(ans, x^1<<(i-1)) + break + } + } + } + } + return +} +``` +#### TypeScript + +```ts +function minBitwiseArray(nums: number[]): number[] { + const ans: number[] = []; + for (const x of nums) { + if (x === 2) { + ans.push(-1); + } else { + for (let i = 1; i < 32; ++i) { + if (((x >> i) & 1) ^ 1) { + ans.push(x ^ (1 << (i - 1))); + break; + } + } + } + } + return ans; +} ``` diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.cpp b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.cpp new file mode 100644 index 0000000000000..79206f73c2455 --- /dev/null +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.cpp @@ -0,0 +1,19 @@ +class Solution { +public: + vector minBitwiseArray(vector& nums) { + vector ans; + for (int x : nums) { + if (x == 2) { + ans.push_back(-1); + } else { + for (int i = 1; i < 32; ++i) { + if (x >> i & 1 ^ 1) { + ans.push_back(x ^ 1 << (i - 1)); + break; + } + } + } + } + return ans; + } +}; diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.go b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.go new file mode 100644 index 0000000000000..2f931a4ab1283 --- /dev/null +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.go @@ -0,0 +1,15 @@ +func minBitwiseArray(nums []int) (ans []int) { + for _, x := range nums { + if x == 2 { + ans = append(ans, -1) + } else { + for i := 1; i < 32; i++ { + if x>>i&1 == 0 { + ans = append(ans, x^1<<(i-1)) + break + } + } + } + } + return +} diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.java b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.java new file mode 100644 index 0000000000000..13433ab0347ed --- /dev/null +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.java @@ -0,0 +1,20 @@ +class Solution { + public int[] minBitwiseArray(List nums) { + int n = nums.size(); + int[] ans = new int[n]; + for (int i = 0; i < n; ++i) { + int x = nums.get(i); + if (x == 2) { + ans[i] = -1; + } else { + for (int j = 1; j < 32; ++j) { + if ((x >> j & 1) == 0) { + ans[i] = x ^ 1 << (j - 1); + break; + } + } + } + } + return ans; + } +} diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.py b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.py new file mode 100644 index 0000000000000..82f2609a941ff --- /dev/null +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.py @@ -0,0 +1,12 @@ +class Solution: + def minBitwiseArray(self, nums: List[int]) -> List[int]: + ans = [] + for x in nums: + if x == 2: + ans.append(-1) + else: + for i in range(1, 32): + if x >> i & 1 ^ 1: + ans.append(x ^ 1 << (i - 1)) + break + return ans diff --git a/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.ts b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.ts new file mode 100644 index 0000000000000..db16f08631bca --- /dev/null +++ b/solution/3300-3399/3315.Construct the Minimum Bitwise Array II/Solution.ts @@ -0,0 +1,16 @@ +function minBitwiseArray(nums: number[]): number[] { + const ans: number[] = []; + for (const x of nums) { + if (x === 2) { + ans.push(-1); + } else { + for (let i = 1; i < 32; ++i) { + if (((x >> i) & 1) ^ 1) { + ans.push(x ^ (1 << (i - 1))); + break; + } + } + } + } + return ans; +} diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md b/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md index 5e02847924663..d63efbbf62a04 100644 --- a/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md @@ -111,32 +111,153 @@ tags: -### 方法一 +### 方法一:动态规划 + +我们定义 $f[i][j]$ 表示在 $\textit{source}$ 的前 $i$ 个字符串,匹配 $\textit{pattern}$ 的前 $j$ 个字符的最大删除次数。初始时 $f[0][0] = 0$,其余 $f[i][j] = -\infty$。 + +对于 $f[i][j]$,我们有两种选择: + +- 我们可以跳过 $\textit{source}$ 的第 $i$ 个字符,此时 $f[i][j] = f[i-1][j] + \text{int}(i-1 \in \textit{targetIndices})$; +- 如果 $\textit{source}[i-1] = \textit{pattern}[j-1]$,我们可以匹配 $\textit{source}$ 的第 $i$ 个字符,此时 $f[i][j] = \max(f[i][j], f[i-1][j-1])$。 + +最终答案即为 $f[m][n]$。 + +时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是 $\textit{source}$ 和 $\textit{pattern}$ 的长度。 #### Python3 ```python - +class Solution: + def maxRemovals(self, source: str, pattern: str, targetIndices: List[int]) -> int: + m, n = len(source), len(pattern) + f = [[-inf] * (n + 1) for _ in range(m + 1)] + f[0][0] = 0 + s = set(targetIndices) + for i, c in enumerate(source, 1): + for j in range(n + 1): + f[i][j] = f[i - 1][j] + int((i - 1) in s) + if j and c == pattern[j - 1]: + f[i][j] = max(f[i][j], f[i - 1][j - 1]) + return f[m][n] ``` #### Java ```java - +class Solution { + public int maxRemovals(String source, String pattern, int[] targetIndices) { + int m = source.length(), n = pattern.length(); + int[][] f = new int[m + 1][n + 1]; + final int inf = Integer.MAX_VALUE / 2; + for (var g : f) { + Arrays.fill(g, -inf); + } + f[0][0] = 0; + int[] s = new int[m]; + for (int i : targetIndices) { + s[i] = 1; + } + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); + } + } + } + return f[m][n]; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxRemovals(string source, string pattern, vector& targetIndices) { + int m = source.length(), n = pattern.length(); + vector> f(m + 1, vector(n + 1, INT_MIN / 2)); + f[0][0] = 0; + + vector s(m); + for (int i : targetIndices) { + s[i] = 1; + } + + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source[i - 1] == pattern[j - 1]) { + f[i][j] = max(f[i][j], f[i - 1][j - 1]); + } + } + } + + return f[m][n]; + } +}; ``` #### Go ```go +func maxRemovals(source string, pattern string, targetIndices []int) int { + m, n := len(source), len(pattern) + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + for j := range f[i] { + f[i][j] = -math.MaxInt32 / 2 + } + } + f[0][0] = 0 + + s := make([]int, m) + for _, i := range targetIndices { + s[i] = 1 + } + + for i := 1; i <= m; i++ { + for j := 0; j <= n; j++ { + f[i][j] = f[i-1][j] + s[i-1] + if j > 0 && source[i-1] == pattern[j-1] { + f[i][j] = max(f[i][j], f[i-1][j-1]) + } + } + } + + return f[m][n] +} +``` +#### TypeScript + +```ts +function maxRemovals(source: string, pattern: string, targetIndices: number[]): number { + const m = source.length; + const n = pattern.length; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(-Infinity)); + f[0][0] = 0; + + const s = Array(m).fill(0); + for (const i of targetIndices) { + s[i] = 1; + } + + for (let i = 1; i <= m; i++) { + for (let j = 0; j <= n; j++) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source[i - 1] === pattern[j - 1]) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); + } + } + } + + return f[m][n]; +} ``` diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md b/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md index 243eb8f5a759b..af58e2c4e6572 100644 --- a/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md @@ -106,32 +106,153 @@ tags: -### Solution 1 +### Solution 1: Dynamic Programming + +We define $f[i][j]$ to represent the maximum number of deletions in the first $i$ characters of $\textit{source}$ that match the first $j$ characters of $\textit{pattern}$. Initially, $f[0][0] = 0$, and the rest $f[i][j] = -\infty$. + +For $f[i][j]$, we have two choices: + +- We can skip the $i$-th character of $\textit{source}$, in which case $f[i][j] = f[i-1][j] + \text{int}(i-1 \in \textit{targetIndices})$; +- If $\textit{source}[i-1] = \textit{pattern}[j-1]$, we can match the $i$-th character of $\textit{source}$, in which case $f[i][j] = \max(f[i][j], f[i-1][j-1])$. + +The final answer is $f[m][n]$. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the lengths of $\textit{source}$ and $\textit{pattern}$, respectively. #### Python3 ```python - +class Solution: + def maxRemovals(self, source: str, pattern: str, targetIndices: List[int]) -> int: + m, n = len(source), len(pattern) + f = [[-inf] * (n + 1) for _ in range(m + 1)] + f[0][0] = 0 + s = set(targetIndices) + for i, c in enumerate(source, 1): + for j in range(n + 1): + f[i][j] = f[i - 1][j] + int((i - 1) in s) + if j and c == pattern[j - 1]: + f[i][j] = max(f[i][j], f[i - 1][j - 1]) + return f[m][n] ``` #### Java ```java - +class Solution { + public int maxRemovals(String source, String pattern, int[] targetIndices) { + int m = source.length(), n = pattern.length(); + int[][] f = new int[m + 1][n + 1]; + final int inf = Integer.MAX_VALUE / 2; + for (var g : f) { + Arrays.fill(g, -inf); + } + f[0][0] = 0; + int[] s = new int[m]; + for (int i : targetIndices) { + s[i] = 1; + } + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); + } + } + } + return f[m][n]; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int maxRemovals(string source, string pattern, vector& targetIndices) { + int m = source.length(), n = pattern.length(); + vector> f(m + 1, vector(n + 1, INT_MIN / 2)); + f[0][0] = 0; + + vector s(m); + for (int i : targetIndices) { + s[i] = 1; + } + + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source[i - 1] == pattern[j - 1]) { + f[i][j] = max(f[i][j], f[i - 1][j - 1]); + } + } + } + + return f[m][n]; + } +}; ``` #### Go ```go +func maxRemovals(source string, pattern string, targetIndices []int) int { + m, n := len(source), len(pattern) + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + for j := range f[i] { + f[i][j] = -math.MaxInt32 / 2 + } + } + f[0][0] = 0 + + s := make([]int, m) + for _, i := range targetIndices { + s[i] = 1 + } + + for i := 1; i <= m; i++ { + for j := 0; j <= n; j++ { + f[i][j] = f[i-1][j] + s[i-1] + if j > 0 && source[i-1] == pattern[j-1] { + f[i][j] = max(f[i][j], f[i-1][j-1]) + } + } + } + + return f[m][n] +} +``` +#### TypeScript + +```ts +function maxRemovals(source: string, pattern: string, targetIndices: number[]): number { + const m = source.length; + const n = pattern.length; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(-Infinity)); + f[0][0] = 0; + + const s = Array(m).fill(0); + for (const i of targetIndices) { + s[i] = 1; + } + + for (let i = 1; i <= m; i++) { + for (let j = 0; j <= n; j++) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source[i - 1] === pattern[j - 1]) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); + } + } + } + + return f[m][n]; +} ``` diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.cpp b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.cpp new file mode 100644 index 0000000000000..272868b4cace9 --- /dev/null +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.cpp @@ -0,0 +1,24 @@ +class Solution { +public: + int maxRemovals(string source, string pattern, vector& targetIndices) { + int m = source.length(), n = pattern.length(); + vector> f(m + 1, vector(n + 1, INT_MIN / 2)); + f[0][0] = 0; + + vector s(m); + for (int i : targetIndices) { + s[i] = 1; + } + + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source[i - 1] == pattern[j - 1]) { + f[i][j] = max(f[i][j], f[i - 1][j - 1]); + } + } + } + + return f[m][n]; + } +}; diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.go b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.go new file mode 100644 index 0000000000000..bb79d00b9d5a7 --- /dev/null +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.go @@ -0,0 +1,27 @@ +func maxRemovals(source string, pattern string, targetIndices []int) int { + m, n := len(source), len(pattern) + f := make([][]int, m+1) + for i := range f { + f[i] = make([]int, n+1) + for j := range f[i] { + f[i][j] = -math.MaxInt32 / 2 + } + } + f[0][0] = 0 + + s := make([]int, m) + for _, i := range targetIndices { + s[i] = 1 + } + + for i := 1; i <= m; i++ { + for j := 0; j <= n; j++ { + f[i][j] = f[i-1][j] + s[i-1] + if j > 0 && source[i-1] == pattern[j-1] { + f[i][j] = max(f[i][j], f[i-1][j-1]) + } + } + } + + return f[m][n] +} diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java new file mode 100644 index 0000000000000..39d2866f4c86b --- /dev/null +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java @@ -0,0 +1,24 @@ +class Solution { + public int maxRemovals(String source, String pattern, int[] targetIndices) { + int m = source.length(), n = pattern.length(); + int[][] f = new int[m + 1][n + 1]; + final int inf = Integer.MAX_VALUE / 2; + for (var g : f) { + Arrays.fill(g, -inf); + } + f[0][0] = 0; + int[] s = new int[m]; + for (int i : targetIndices) { + s[i] = 1; + } + for (int i = 1; i <= m; ++i) { + for (int j = 0; j <= n; ++j) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); + } + } + } + return f[m][n]; + } +} diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.py b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.py new file mode 100644 index 0000000000000..b33ab2b21fb05 --- /dev/null +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.py @@ -0,0 +1,12 @@ +class Solution: + def maxRemovals(self, source: str, pattern: str, targetIndices: List[int]) -> int: + m, n = len(source), len(pattern) + f = [[-inf] * (n + 1) for _ in range(m + 1)] + f[0][0] = 0 + s = set(targetIndices) + for i, c in enumerate(source, 1): + for j in range(n + 1): + f[i][j] = f[i - 1][j] + int((i - 1) in s) + if j and c == pattern[j - 1]: + f[i][j] = max(f[i][j], f[i - 1][j - 1]) + return f[m][n] diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.ts b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.ts new file mode 100644 index 0000000000000..46f4788d249bc --- /dev/null +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.ts @@ -0,0 +1,22 @@ +function maxRemovals(source: string, pattern: string, targetIndices: number[]): number { + const m = source.length; + const n = pattern.length; + const f: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(-Infinity)); + f[0][0] = 0; + + const s = Array(m).fill(0); + for (const i of targetIndices) { + s[i] = 1; + } + + for (let i = 1; i <= m; i++) { + for (let j = 0; j <= n; j++) { + f[i][j] = f[i - 1][j] + s[i - 1]; + if (j > 0 && source[i - 1] === pattern[j - 1]) { + f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); + } + } + } + + return f[m][n]; +} From ccc3809b686056f19979ff902335de2182712856 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 23 Oct 2024 09:28:09 +0800 Subject: [PATCH 2/2] fix: code style --- .../3316.Find Maximum Removals From Source String/README.md | 2 +- .../3316.Find Maximum Removals From Source String/README_EN.md | 2 +- .../3316.Find Maximum Removals From Source String/Solution.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md b/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md index d63efbbf62a04..1e401ea7e5c20 100644 --- a/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/README.md @@ -162,7 +162,7 @@ class Solution { for (int i = 1; i <= m; ++i) { for (int j = 0; j <= n; ++j) { f[i][j] = f[i - 1][j] + s[i - 1]; - if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { + if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); } } diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md b/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md index af58e2c4e6572..3c83f2c940da1 100644 --- a/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/README_EN.md @@ -157,7 +157,7 @@ class Solution { for (int i = 1; i <= m; ++i) { for (int j = 0; j <= n; ++j) { f[i][j] = f[i - 1][j] + s[i - 1]; - if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { + if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); } } diff --git a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java index 39d2866f4c86b..1ffea1ce83b8c 100644 --- a/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java +++ b/solution/3300-3399/3316.Find Maximum Removals From Source String/Solution.java @@ -14,7 +14,7 @@ public int maxRemovals(String source, String pattern, int[] targetIndices) { for (int i = 1; i <= m; ++i) { for (int j = 0; j <= n; ++j) { f[i][j] = f[i - 1][j] + s[i - 1]; - if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { + if (j > 0 && source.charAt(i - 1) == pattern.charAt(j - 1)) { f[i][j] = Math.max(f[i][j], f[i - 1][j - 1]); } }