From 2676cdeea412821b38def3b65055e2d96c05339b Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 16 Mar 2024 23:30:26 +0800 Subject: [PATCH] feat: add solutions to lc problems: No.1980,1981 * No.1980.Find Unique Binary String * No.1981.Minimize the Difference Between Target and Chosen Elements --- .../1980.Find Unique Binary String/README.md | 17 +++- .../README_EN.md | 25 +++++- .../Solution.ts | 12 +++ .../README.md | 62 +++++++-------- .../README_EN.md | 78 ++++++++++--------- 5 files changed, 123 insertions(+), 71 deletions(-) create mode 100644 solution/1900-1999/1980.Find Unique Binary String/Solution.ts diff --git a/solution/1900-1999/1980.Find Unique Binary String/README.md b/solution/1900-1999/1980.Find Unique Binary String/README.md index 814bc876c3ca3..89b45a04a9934 100644 --- a/solution/1900-1999/1980.Find Unique Binary String/README.md +++ b/solution/1900-1999/1980.Find Unique Binary String/README.md @@ -57,7 +57,7 @@ 然后我们从 $0$ 开始枚举长度为 $n$ 的二进制字符串中 `'1'` 出现的次数 $i$,如果 $mask$ 的第 $i$ 位为 $0$,则说明长度为 $n$ 的二进制字符串中 `'1'` 出现次数为 $i$ 的字符串不存在,我们可以将这个字符串作为答案返回。 -时间复杂度 $O(L)$,空间复杂度 $O(1)$。其中 $L$ 为 `nums` 中字符串的总长度。 +时间复杂度 $O(L)$,其中 $L$ 为 `nums` 中字符串的总长度。空间复杂度 $O(1)$。 @@ -127,6 +127,21 @@ func findDifferentBinaryString(nums []string) string { } ``` +```ts +function findDifferentBinaryString(nums: string[]): string { + let mask = 0; + for (let x of nums) { + const cnt = x.split('').filter(c => c === '1').length; + mask |= 1 << cnt; + } + for (let i = 0; ; ++i) { + if (((mask >> i) & 1) === 0) { + return '1'.repeat(i) + '0'.repeat(nums.length - i); + } + } +} +``` + ```cs public class Solution { public string FindDifferentBinaryString(string[] nums) { diff --git a/solution/1900-1999/1980.Find Unique Binary String/README_EN.md b/solution/1900-1999/1980.Find Unique Binary String/README_EN.md index ba24802b6faed..499f12dae2fb5 100644 --- a/solution/1900-1999/1980.Find Unique Binary String/README_EN.md +++ b/solution/1900-1999/1980.Find Unique Binary String/README_EN.md @@ -46,7 +46,15 @@ ## Solutions -### Solution 1 +### Solution 1: Counting + Enumeration + +Since the number of occurrences of '1' in a binary string of length $n$ can be $0, 1, 2, \cdots, n$ (there are $n + 1$ possibilities), we can certainly find a new binary string that has a different number of '1's from every string in `nums`. + +We can use an integer $mask$ to record the occurrence of '1' in all strings, i.e., the $i$-th bit of $mask$ is $1$ indicates that there is a string of length $n$ in which '1' appears $i$ times, otherwise it does not exist. + +Then we start to enumerate the number of times '1' appears in a binary string of length $n$ from $0$. If the $i$-th bit of $mask$ is $0$, it means that there is no string of length $n$ in which '1' appears $i$ times. We can return this string as the answer. + +The time complexity is $O(L)$, where $L$ is the total length of the strings in `nums`. The space complexity is $O(1)$. @@ -116,6 +124,21 @@ func findDifferentBinaryString(nums []string) string { } ``` +```ts +function findDifferentBinaryString(nums: string[]): string { + let mask = 0; + for (let x of nums) { + const cnt = x.split('').filter(c => c === '1').length; + mask |= 1 << cnt; + } + for (let i = 0; ; ++i) { + if (((mask >> i) & 1) === 0) { + return '1'.repeat(i) + '0'.repeat(nums.length - i); + } + } +} +``` + ```cs public class Solution { public string FindDifferentBinaryString(string[] nums) { diff --git a/solution/1900-1999/1980.Find Unique Binary String/Solution.ts b/solution/1900-1999/1980.Find Unique Binary String/Solution.ts new file mode 100644 index 0000000000000..c70c0db4e2fb5 --- /dev/null +++ b/solution/1900-1999/1980.Find Unique Binary String/Solution.ts @@ -0,0 +1,12 @@ +function findDifferentBinaryString(nums: string[]): string { + let mask = 0; + for (let x of nums) { + const cnt = x.split('').filter(c => c === '1').length; + mask |= 1 << cnt; + } + for (let i = 0; ; ++i) { + if (((mask >> i) & 1) === 0) { + return '1'.repeat(i) + '0'.repeat(nums.length - i); + } + } +} diff --git a/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README.md b/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README.md index 612966dc44e12..bcc8e0cf3d501 100644 --- a/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README.md +++ b/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README.md @@ -98,6 +98,34 @@ class Solution: return min(abs(v - target) for v in f) ``` +```java +class Solution { + public int minimizeTheDifference(int[][] mat, int target) { + boolean[] f = {true}; + for (var row : mat) { + int mx = 0; + for (int x : row) { + mx = Math.max(mx, x); + } + boolean[] g = new boolean[f.length + mx]; + for (int x : row) { + for (int j = x; j < f.length + x; ++j) { + g[j] |= f[j - x]; + } + } + f = g; + } + int ans = 1 << 30; + for (int j = 0; j < f.length; ++j) { + if (f[j]) { + ans = Math.min(ans, Math.abs(j - target)); + } + } + return ans; + } +} +``` + ```java class Solution { public int minimizeTheDifference(int[][] mat, int target) { @@ -179,38 +207,4 @@ func abs(x int) int { -### 方法二 - - - -```java -class Solution { - public int minimizeTheDifference(int[][] mat, int target) { - boolean[] f = {true}; - for (var row : mat) { - int mx = 0; - for (int x : row) { - mx = Math.max(mx, x); - } - boolean[] g = new boolean[f.length + mx]; - for (int x : row) { - for (int j = x; j < f.length + x; ++j) { - g[j] |= f[j - x]; - } - } - f = g; - } - int ans = 1 << 30; - for (int j = 0; j < f.length; ++j) { - if (f[j]) { - ans = Math.min(ans, Math.abs(j - target)); - } - } - return ans; - } -} -``` - - - diff --git a/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README_EN.md b/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README_EN.md index 16127154dd5ca..561f8ea4e3206 100644 --- a/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README_EN.md +++ b/solution/1900-1999/1981.Minimize the Difference Between Target and Chosen Elements/README_EN.md @@ -61,7 +61,21 @@ The absolute difference is 1. ## Solutions -### Solution 1 +### Solution 1: Dynamic Programming (Grouped Knapsack) + +Let $f[i][j]$ represent whether it is possible to select elements from the first $i$ rows with a sum of $j$. Then we have the state transition equation: + +$$ +f[i][j] = \begin{cases} 1 & \text{if there exists } x \in row[i] \text{ such that } f[i - 1][j - x] = 1 \\ 0 & \text{otherwise} \end{cases} +$$ + +where $row[i]$ represents the set of elements in the $i$-th row. + +Since $f[i][j]$ is only related to $f[i - 1][j]$, we can use a rolling array to optimize the space complexity. + +Finally, we traverse the $f$ array to find the smallest absolute difference. + +The time complexity is $O(m^2 \times n \times C)$ and the space complexity is $O(m \times C)$. Here, $m$ and $n$ are the number of rows and columns of the matrix, respectively, and $C$ is the maximum value of the matrix elements. @@ -74,6 +88,34 @@ class Solution: return min(abs(v - target) for v in f) ``` +```java +class Solution { + public int minimizeTheDifference(int[][] mat, int target) { + boolean[] f = {true}; + for (var row : mat) { + int mx = 0; + for (int x : row) { + mx = Math.max(mx, x); + } + boolean[] g = new boolean[f.length + mx]; + for (int x : row) { + for (int j = x; j < f.length + x; ++j) { + g[j] |= f[j - x]; + } + } + f = g; + } + int ans = 1 << 30; + for (int j = 0; j < f.length; ++j) { + if (f[j]) { + ans = Math.min(ans, Math.abs(j - target)); + } + } + return ans; + } +} +``` + ```java class Solution { public int minimizeTheDifference(int[][] mat, int target) { @@ -155,38 +197,4 @@ func abs(x int) int { -### Solution 2 - - - -```java -class Solution { - public int minimizeTheDifference(int[][] mat, int target) { - boolean[] f = {true}; - for (var row : mat) { - int mx = 0; - for (int x : row) { - mx = Math.max(mx, x); - } - boolean[] g = new boolean[f.length + mx]; - for (int x : row) { - for (int j = x; j < f.length + x; ++j) { - g[j] |= f[j - x]; - } - } - f = g; - } - int ans = 1 << 30; - for (int j = 0; j < f.length; ++j) { - if (f[j]) { - ans = Math.min(ans, Math.abs(j - target)); - } - } - return ans; - } -} -``` - - -