From 130b08812870288cac2cdeb14282685b5481223a Mon Sep 17 00:00:00 2001 From: yanglbme Date: Tue, 4 Jun 2024 12:40:08 +0800 Subject: [PATCH] feat: update solutions to lc problems: No.412,416 --- solution/0400-0499/0412.Fizz Buzz/README.md | 72 ++++++++++++------- .../0400-0499/0412.Fizz Buzz/README_EN.md | 72 ++++++++++++------- .../0400-0499/0412.Fizz Buzz/Solution.cpp | 12 +++- solution/0400-0499/0412.Fizz Buzz/Solution.go | 5 +- solution/0400-0499/0412.Fizz Buzz/Solution.js | 25 ++++--- .../0400-0499/0412.Fizz Buzz/Solution.php | 26 +++---- .../0413.Arithmetic Slices/README.md | 35 ++------- .../0413.Arithmetic Slices/README_EN.md | 50 +++++-------- .../0413.Arithmetic Slices/Solution.py | 6 +- .../0413.Arithmetic Slices/Solution2.py | 12 ---- .../0414.Third Maximum Number/README.md | 15 +++- .../0414.Third Maximum Number/README_EN.md | 15 +++- .../0416.Partition Equal Subset Sum/README.md | 18 +++-- .../README_EN.md | 30 +++++--- .../Solution.js | 4 +- .../Solution.ts | 4 +- 16 files changed, 220 insertions(+), 181 deletions(-) delete mode 100644 solution/0400-0499/0413.Arithmetic Slices/Solution2.py diff --git a/solution/0400-0499/0412.Fizz Buzz/README.md b/solution/0400-0499/0412.Fizz Buzz/README.md index 79138b9b875bc..e700c0a3089e9 100644 --- a/solution/0400-0499/0412.Fizz Buzz/README.md +++ b/solution/0400-0499/0412.Fizz Buzz/README.md @@ -63,7 +63,11 @@ tags: -### 方法一 +### 方法一:模拟 + +我们遍历从 1 到 n 的每个整数,对于每个整数,我们检查它是否是 3 和 5 的倍数,或者只是 3 的倍数,或者只是 5 的倍数。根据检查的结果,我们将相应的字符串添加到答案数组中。 + +时间复杂度 $O(n)$,其中 $n$ 是题目给定的整数。忽略答案数组的空间消耗,空间复杂度 $O(1)$。 @@ -118,9 +122,15 @@ public: vector ans; for (int i = 1; i <= n; ++i) { string s = ""; - if (i % 3 == 0) s += "Fizz"; - if (i % 5 == 0) s += "Buzz"; - if (s.size() == 0) s = to_string(i); + if (i % 3 == 0) { + s += "Fizz"; + } + if (i % 5 == 0) { + s += "Buzz"; + } + if (s.empty()) { + s = to_string(i); + } ans.push_back(s); } return ans; @@ -131,8 +141,7 @@ public: #### Go ```go -func fizzBuzz(n int) []string { - var ans []string +func fizzBuzz(n int) (ans []string) { for i := 1; i <= n; i++ { s := &strings.Builder{} if i%3 == 0 { @@ -146,22 +155,31 @@ func fizzBuzz(n int) []string { } ans = append(ans, s.String()) } - return ans + return } ``` #### JavaScript ```js -const fizzBuzz = function (n) { - let arr = []; - for (let i = 1; i <= n; i++) { - if (i % 15 === 0) arr.push('FizzBuzz'); - else if (i % 3 === 0) arr.push('Fizz'); - else if (i % 5 === 0) arr.push('Buzz'); - else arr.push(`${i}`); +/** + * @param {number} n + * @return {string[]} + */ +var fizzBuzz = function (n) { + const ans = []; + for (let i = 1; i <= n; ++i) { + if (i % 15 === 0) { + ans.push('FizzBuzz'); + } else if (i % 3 === 0) { + ans.push('Fizz'); + } else if (i % 5 === 0) { + ans.push('Buzz'); + } else { + ans.push(`${i}`); + } } - return arr; + return ans; }; ``` @@ -174,19 +192,21 @@ class Solution { * @return String[] */ function fizzBuzz($n) { - $rs = []; - for ($i = 1; $i <= $n; $i++) { - if ($i % 3 != 0 && $i % 5 != 0) { - array_push($rs, strval($i)); - } elseif ($i % 3 == 0 && $i % 5 != 0) { - array_push($rs, 'Fizz'); - } elseif ($i % 3 != 0 && $i % 5 == 0) { - array_push($rs, 'Buzz'); - } else { - array_push($rs, 'FizzBuzz'); + $ans = []; + for ($i = 1; $i <= $n; ++$i) { + $s = ''; + if ($i % 3 == 0) { + $s .= 'Fizz'; + } + if ($i % 5 == 0) { + $s .= 'Buzz'; + } + if (strlen($s) == 0) { + $s .= $i; } + $ans[] = $s; } - return $rs; + return $ans; } } ``` diff --git a/solution/0400-0499/0412.Fizz Buzz/README_EN.md b/solution/0400-0499/0412.Fizz Buzz/README_EN.md index 06e315a49b9e9..088605636ac28 100644 --- a/solution/0400-0499/0412.Fizz Buzz/README_EN.md +++ b/solution/0400-0499/0412.Fizz Buzz/README_EN.md @@ -51,7 +51,11 @@ tags: -### Solution 1 +### Solution 1: Simulation + +We iterate through each integer from 1 to $n$. For each integer, we check whether it is a multiple of both 3 and 5, or just a multiple of 3, or just a multiple of 5. Based on the check result, we add the corresponding string to the answer array. + +The time complexity is $O(n)$, where $n$ is the integer given in the problem. Ignoring the space consumption of the answer array, the space complexity is $O(1)$. @@ -106,9 +110,15 @@ public: vector ans; for (int i = 1; i <= n; ++i) { string s = ""; - if (i % 3 == 0) s += "Fizz"; - if (i % 5 == 0) s += "Buzz"; - if (s.size() == 0) s = to_string(i); + if (i % 3 == 0) { + s += "Fizz"; + } + if (i % 5 == 0) { + s += "Buzz"; + } + if (s.empty()) { + s = to_string(i); + } ans.push_back(s); } return ans; @@ -119,8 +129,7 @@ public: #### Go ```go -func fizzBuzz(n int) []string { - var ans []string +func fizzBuzz(n int) (ans []string) { for i := 1; i <= n; i++ { s := &strings.Builder{} if i%3 == 0 { @@ -134,22 +143,31 @@ func fizzBuzz(n int) []string { } ans = append(ans, s.String()) } - return ans + return } ``` #### JavaScript ```js -const fizzBuzz = function (n) { - let arr = []; - for (let i = 1; i <= n; i++) { - if (i % 15 === 0) arr.push('FizzBuzz'); - else if (i % 3 === 0) arr.push('Fizz'); - else if (i % 5 === 0) arr.push('Buzz'); - else arr.push(`${i}`); +/** + * @param {number} n + * @return {string[]} + */ +var fizzBuzz = function (n) { + const ans = []; + for (let i = 1; i <= n; ++i) { + if (i % 15 === 0) { + ans.push('FizzBuzz'); + } else if (i % 3 === 0) { + ans.push('Fizz'); + } else if (i % 5 === 0) { + ans.push('Buzz'); + } else { + ans.push(`${i}`); + } } - return arr; + return ans; }; ``` @@ -162,19 +180,21 @@ class Solution { * @return String[] */ function fizzBuzz($n) { - $rs = []; - for ($i = 1; $i <= $n; $i++) { - if ($i % 3 != 0 && $i % 5 != 0) { - array_push($rs, strval($i)); - } elseif ($i % 3 == 0 && $i % 5 != 0) { - array_push($rs, 'Fizz'); - } elseif ($i % 3 != 0 && $i % 5 == 0) { - array_push($rs, 'Buzz'); - } else { - array_push($rs, 'FizzBuzz'); + $ans = []; + for ($i = 1; $i <= $n; ++$i) { + $s = ''; + if ($i % 3 == 0) { + $s .= 'Fizz'; + } + if ($i % 5 == 0) { + $s .= 'Buzz'; + } + if (strlen($s) == 0) { + $s .= $i; } + $ans[] = $s; } - return $rs; + return $ans; } } ``` diff --git a/solution/0400-0499/0412.Fizz Buzz/Solution.cpp b/solution/0400-0499/0412.Fizz Buzz/Solution.cpp index 63d3912d5c1f1..e52b0ee9dbb8b 100644 --- a/solution/0400-0499/0412.Fizz Buzz/Solution.cpp +++ b/solution/0400-0499/0412.Fizz Buzz/Solution.cpp @@ -4,9 +4,15 @@ class Solution { vector ans; for (int i = 1; i <= n; ++i) { string s = ""; - if (i % 3 == 0) s += "Fizz"; - if (i % 5 == 0) s += "Buzz"; - if (s.size() == 0) s = to_string(i); + if (i % 3 == 0) { + s += "Fizz"; + } + if (i % 5 == 0) { + s += "Buzz"; + } + if (s.empty()) { + s = to_string(i); + } ans.push_back(s); } return ans; diff --git a/solution/0400-0499/0412.Fizz Buzz/Solution.go b/solution/0400-0499/0412.Fizz Buzz/Solution.go index dcc393a49511a..0a7f2deab0707 100644 --- a/solution/0400-0499/0412.Fizz Buzz/Solution.go +++ b/solution/0400-0499/0412.Fizz Buzz/Solution.go @@ -1,5 +1,4 @@ -func fizzBuzz(n int) []string { - var ans []string +func fizzBuzz(n int) (ans []string) { for i := 1; i <= n; i++ { s := &strings.Builder{} if i%3 == 0 { @@ -13,5 +12,5 @@ func fizzBuzz(n int) []string { } ans = append(ans, s.String()) } - return ans + return } \ No newline at end of file diff --git a/solution/0400-0499/0412.Fizz Buzz/Solution.js b/solution/0400-0499/0412.Fizz Buzz/Solution.js index 99ebd305a505d..e7a561eb72a54 100644 --- a/solution/0400-0499/0412.Fizz Buzz/Solution.js +++ b/solution/0400-0499/0412.Fizz Buzz/Solution.js @@ -1,10 +1,19 @@ -const fizzBuzz = function (n) { - let arr = []; - for (let i = 1; i <= n; i++) { - if (i % 15 === 0) arr.push('FizzBuzz'); - else if (i % 3 === 0) arr.push('Fizz'); - else if (i % 5 === 0) arr.push('Buzz'); - else arr.push(`${i}`); +/** + * @param {number} n + * @return {string[]} + */ +var fizzBuzz = function (n) { + const ans = []; + for (let i = 1; i <= n; ++i) { + if (i % 15 === 0) { + ans.push('FizzBuzz'); + } else if (i % 3 === 0) { + ans.push('Fizz'); + } else if (i % 5 === 0) { + ans.push('Buzz'); + } else { + ans.push(`${i}`); + } } - return arr; + return ans; }; diff --git a/solution/0400-0499/0412.Fizz Buzz/Solution.php b/solution/0400-0499/0412.Fizz Buzz/Solution.php index 9e8e63c3202f2..761ccfc1ce90d 100644 --- a/solution/0400-0499/0412.Fizz Buzz/Solution.php +++ b/solution/0400-0499/0412.Fizz Buzz/Solution.php @@ -4,18 +4,20 @@ class Solution { * @return String[] */ function fizzBuzz($n) { - $rs = []; - for ($i = 1; $i <= $n; $i++) { - if ($i % 3 != 0 && $i % 5 != 0) { - array_push($rs, strval($i)); - } elseif ($i % 3 == 0 && $i % 5 != 0) { - array_push($rs, 'Fizz'); - } elseif ($i % 3 != 0 && $i % 5 == 0) { - array_push($rs, 'Buzz'); - } else { - array_push($rs, 'FizzBuzz'); + $ans = []; + for ($i = 1; $i <= $n; ++$i) { + $s = ''; + if ($i % 3 == 0) { + $s .= 'Fizz'; } + if ($i % 5 == 0) { + $s .= 'Buzz'; + } + if (strlen($s) == 0) { + $s .= $i; + } + $ans[] = $s; } - return $rs; + return $ans; } -} +} \ No newline at end of file diff --git a/solution/0400-0499/0413.Arithmetic Slices/README.md b/solution/0400-0499/0413.Arithmetic Slices/README.md index b1b0d653e7489..af71bc231a5d4 100644 --- a/solution/0400-0499/0413.Arithmetic Slices/README.md +++ b/solution/0400-0499/0413.Arithmetic Slices/README.md @@ -67,7 +67,7 @@ tags: 我们用 $d$ 表示当前相邻两个元素的差值,用 $cnt$ 表示当前等差数列的长度,初始时 $d = 3000$, $cnt = 2$。 -遍历数组 `nums`,对于相邻的两个元素 $a$ 和 $b$,如果 $b - a = d$,则说明当前元素 $b$ 也属于当前等差数列,此时 $cnt$ 自增 1;否则说明当前元素 $b$ 不属于当前等差数列,此时更新 $d = b - a$,$cnt = 2$。如果 $cnt \ge 3$,则说明当前等差数列的长度至少为 3,此时等差数列的个数为 $cnt - 2$,将其加到答案中。 +遍历数组 `nums`,对于相邻的两个元素 $a$ 和 $b$,如果 $b - a = d$,则说明当前元素 $b$ 也属于当前等差数列,此时 $cnt$ 自增 1;否则说明当前元素 $b$ 不属于当前等差数列,此时更新 $d = b - a$,且 $cnt = 2$。如果 $cnt \ge 3$,则说明当前等差数列的长度至少为 3,此时等差数列的个数为 $cnt - 2$,将其加到答案中。 遍历结束后,即可得到答案。 @@ -87,15 +87,15 @@ tags: ```python class Solution: def numberOfArithmeticSlices(self, nums: List[int]) -> int: - ans, cnt = 0, 2 + ans = cnt = 0 d = 3000 for a, b in pairwise(nums): if b - a == d: cnt += 1 else: d = b - a - cnt = 2 - ans += max(0, cnt - 2) + cnt = 0 + ans += cnt return ans ``` @@ -187,31 +187,4 @@ function numberOfArithmeticSlices(nums: number[]): number { - - -### 方法二 - - - -#### Python3 - -```python -class Solution: - def numberOfArithmeticSlices(self, nums: List[int]) -> int: - ans = cnt = 0 - d = 3000 - for a, b in pairwise(nums): - if b - a == d: - cnt += 1 - else: - d = b - a - cnt = 0 - ans += cnt - return ans -``` - - - - - diff --git a/solution/0400-0499/0413.Arithmetic Slices/README_EN.md b/solution/0400-0499/0413.Arithmetic Slices/README_EN.md index 33091be4eafb2..c9bf3367f783e 100644 --- a/solution/0400-0499/0413.Arithmetic Slices/README_EN.md +++ b/solution/0400-0499/0413.Arithmetic Slices/README_EN.md @@ -57,7 +57,22 @@ tags: -### Solution 1 +### Solution 1: Iteration and Counting + +We use $d$ to represent the current difference between two adjacent elements, and $cnt$ to represent the length of the current arithmetic sequence. Initially, $d = 3000$, $cnt = 2$. + +We iterate through the array `nums`. For two adjacent elements $a$ and $b$, if $b - a = d$, it means that the current element $b$ also belongs to the current arithmetic sequence, and we increment $cnt$ by 1. Otherwise, it means that the current element $b$ does not belong to the current arithmetic sequence, and we update $d = b - a$, and $cnt = 2$. If $cnt \ge 3$, it means that the length of the current arithmetic sequence is at least 3, and the number of arithmetic sequences is $cnt - 2$, which we add to the answer. + +After the iteration, we can get the answer. + +In the code implementation, we can also initialize $cnt$ to $0$, and when resetting $cnt$, we directly set $cnt$ to $0$. When adding to the answer, we directly add $cnt$. + +The time complexity is $O(n)$, and the space complexity is $O(1)$. Where $n$ is the length of the array `nums`. + +Similar problems: + +- [1513. Number of Substrings With Only 1s](https://github.com/doocs/leetcode/blob/main/solution/1500-1599/1513.Number%20of%20Substrings%20With%20Only%201s/README_EN.md) +- [2348. Number of Zero-Filled Subarrays](https://github.com/doocs/leetcode/blob/main/solution/2300-2399/2348.Number%20of%20Zero-Filled%20Subarrays/README_EN.md) @@ -66,15 +81,15 @@ tags: ```python class Solution: def numberOfArithmeticSlices(self, nums: List[int]) -> int: - ans, cnt = 0, 2 + ans = cnt = 0 d = 3000 for a, b in pairwise(nums): if b - a == d: cnt += 1 else: d = b - a - cnt = 2 - ans += max(0, cnt - 2) + cnt = 0 + ans += cnt return ans ``` @@ -166,31 +181,4 @@ function numberOfArithmeticSlices(nums: number[]): number { - - -### Solution 2 - - - -#### Python3 - -```python -class Solution: - def numberOfArithmeticSlices(self, nums: List[int]) -> int: - ans = cnt = 0 - d = 3000 - for a, b in pairwise(nums): - if b - a == d: - cnt += 1 - else: - d = b - a - cnt = 0 - ans += cnt - return ans -``` - - - - - diff --git a/solution/0400-0499/0413.Arithmetic Slices/Solution.py b/solution/0400-0499/0413.Arithmetic Slices/Solution.py index 9b59a018148de..23e3f897c6bc2 100644 --- a/solution/0400-0499/0413.Arithmetic Slices/Solution.py +++ b/solution/0400-0499/0413.Arithmetic Slices/Solution.py @@ -1,12 +1,12 @@ class Solution: def numberOfArithmeticSlices(self, nums: List[int]) -> int: - ans, cnt = 0, 2 + ans = cnt = 0 d = 3000 for a, b in pairwise(nums): if b - a == d: cnt += 1 else: d = b - a - cnt = 2 - ans += max(0, cnt - 2) + cnt = 0 + ans += cnt return ans diff --git a/solution/0400-0499/0413.Arithmetic Slices/Solution2.py b/solution/0400-0499/0413.Arithmetic Slices/Solution2.py deleted file mode 100644 index 23e3f897c6bc2..0000000000000 --- a/solution/0400-0499/0413.Arithmetic Slices/Solution2.py +++ /dev/null @@ -1,12 +0,0 @@ -class Solution: - def numberOfArithmeticSlices(self, nums: List[int]) -> int: - ans = cnt = 0 - d = 3000 - for a, b in pairwise(nums): - if b - a == d: - cnt += 1 - else: - d = b - a - cnt = 0 - ans += cnt - return ans diff --git a/solution/0400-0499/0414.Third Maximum Number/README.md b/solution/0400-0499/0414.Third Maximum Number/README.md index 6cf326dfc12bc..220f5ce00eb56 100644 --- a/solution/0400-0499/0414.Third Maximum Number/README.md +++ b/solution/0400-0499/0414.Third Maximum Number/README.md @@ -63,7 +63,20 @@ tags: -### 方法一 +### 方法一:一次遍历 + +我们可以使用三个变量 $m_1$, $m_2$, $m_3$ 分别表示数组中的第一大、第二大和第三大的数。初始时,我们将这三个变量都赋值为负无穷大。 + +然后,我们遍历数组中的每个数,对于每个数,我们将其与 $m_1$, $m_2$, $m_3$ 进行比较,根据比较的结果更新这三个变量。具体地,我们遍历数组中的每个数,对于每个数: + +- 如果这个数等于 $m_1$, $m_2$, $m_3$ 中的任何一个,我们跳过这个数; +- 如果这个数大于 $m_1$,我们将 $m_1$, $m_2$, $m_3$ 的值更新为 $m_2$, $m_3$, 这个数; +- 如果这个数大于 $m_2$,我们将 $m_2$, $m_3$ 的值更新为 $m_3$, 这个数; +- 如果这个数大于 $m_3$,我们将 $m_3$ 的值更新为这个数。 + +最后,如果 $m_3$ 的值没有被更新,说明数组中不存在第三大的数,那么我们返回 $m_1$,否则我们返回 $m_3$。 + +时间复杂度 $O(n)$,其中 $n$ 是数组 `nums` 的长度。空间复杂度 $O(1)$。 diff --git a/solution/0400-0499/0414.Third Maximum Number/README_EN.md b/solution/0400-0499/0414.Third Maximum Number/README_EN.md index 1fe8d1a9a6ec0..a6c1da296f85f 100644 --- a/solution/0400-0499/0414.Third Maximum Number/README_EN.md +++ b/solution/0400-0499/0414.Third Maximum Number/README_EN.md @@ -70,7 +70,20 @@ The third distinct maximum is 1. -### Solution 1 +### Solution 1: Single Pass + +We can use three variables $m_1$, $m_2$, and $m_3$ to represent the first, second, and third largest numbers in the array respectively. Initially, we set these three variables to negative infinity. + +Then, we iterate through each number in the array. For each number: + +- If it equals any of $m_1$, $m_2$, or $m_3$, we skip this number. +- If it is greater than $m_1$, we update the values of $m_1$, $m_2$, and $m_3$ to $m_2$, $m_3$, and this number respectively. +- If it is greater than $m_2$, we update the values of $m_2$ and $m_3$ to $m_3$ and this number respectively. +- If it is greater than $m_3$, we update the value of $m_3$ to this number. + +Finally, if the value of $m_3$ has not been updated, it means that there is no third largest number in the array, so we return $m_1$. Otherwise, we return $m_3$. + +The time complexity is $O(n)$, where $n$ is the length of the array `nums`. The space complexity is $O(1)$. diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/README.md b/solution/0400-0499/0416.Partition Equal Subset Sum/README.md index 6aefd86541a21..11b26eb1296c2 100644 --- a/solution/0400-0499/0416.Partition Equal Subset Sum/README.md +++ b/solution/0400-0499/0416.Partition Equal Subset Sum/README.md @@ -65,9 +65,7 @@ $$ 最终答案为 $f[n][m]$。 -注意到 $f[i][j]$ 只与 $f[i - 1][\cdot]$ 有关,因此我们可以将二维数组压缩成一维数组。 - -时间复杂度 $O(n \times m)$,空间复杂度 $O(m)$。其中 $n$ 是数组的长度,而 $m$ 是数组的总和的一半。 +时间复杂度 $(m \times n)$,空间复杂度 $(m \times n)$。其中 $m$ 和 $n$ 分别为数组的总和的一半和数组的长度。 @@ -179,9 +177,7 @@ function canPartition(nums: number[]): boolean { } const n = nums.length; const m = s >> 1; - const f: boolean[][] = Array(n + 1) - .fill(0) - .map(() => Array(m + 1).fill(false)); + const f: boolean[][] = Array.from({ length: n + 1 }, () => Array(m + 1).fill(false)); f[0][0] = true; for (let i = 1; i <= n; ++i) { const x = nums[i - 1]; @@ -245,9 +241,7 @@ var canPartition = function (nums) { } const n = nums.length; const m = s >> 1; - const f = Array(n + 1) - .fill(0) - .map(() => Array(m + 1).fill(false)); + const f = Array.from({ length: n + 1 }, () => Array(m + 1).fill(false)); f[0][0] = true; for (let i = 1; i <= n; ++i) { const x = nums[i - 1]; @@ -265,7 +259,11 @@ var canPartition = function (nums) { -### 方法二 +### 方法二:动态规划(空间优化) + +我们注意到,方法一中 $f[i][j]$ 只与 $f[i - 1][\cdot]$ 有关,因此我们可以将二维数组压缩成一维数组。 + +时间复杂度 $O(n \times m)$,空间复杂度 $O(m)$。其中 $n$ 是数组的长度,而 $m$ 是数组的总和的一半。 diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md b/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md index c73d9f767e0eb..1138a5a641ab5 100644 --- a/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md +++ b/solution/0400-0499/0416.Partition Equal Subset Sum/README_EN.md @@ -50,7 +50,21 @@ tags: -### Solution 1 +### Solution 1: Dynamic Programming + +First, we calculate the total sum $s$ of the array. If the total sum is odd, it cannot be divided into two subsets with equal sums, so we directly return `false`. If the total sum is even, we set the target subset sum to $m = \frac{s}{2}$. The problem is then transformed into: does there exist a subset whose element sum is $m$? + +We define $f[i][j]$ to represent whether it is possible to select several numbers from the first $i$ numbers so that their sum is exactly $j$. Initially, $f[0][0] = true$ and the rest $f[i][j] = false$. The answer is $f[n][m]$. + +Considering $f[i][j]$, if we select the $i$-th number $x$, then $f[i][j] = f[i - 1][j - x]$. If we do not select the $i$-th number $x$, then $f[i][j] = f[i - 1][j]$. Therefore, the state transition equation is: + +$$ +f[i][j] = f[i - 1][j] \text{ or } f[i - 1][j - x] \text{ if } j \geq x +$$ + +The final answer is $f[n][m]$. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Where $m$ and $n$ are half of the total sum of the array and the length of the array, respectively. @@ -162,9 +176,7 @@ function canPartition(nums: number[]): boolean { } const n = nums.length; const m = s >> 1; - const f: boolean[][] = Array(n + 1) - .fill(0) - .map(() => Array(m + 1).fill(false)); + const f: boolean[][] = Array.from({ length: n + 1 }, () => Array(m + 1).fill(false)); f[0][0] = true; for (let i = 1; i <= n; ++i) { const x = nums[i - 1]; @@ -228,9 +240,7 @@ var canPartition = function (nums) { } const n = nums.length; const m = s >> 1; - const f = Array(n + 1) - .fill(0) - .map(() => Array(m + 1).fill(false)); + const f = Array.from({ length: n + 1 }, () => Array(m + 1).fill(false)); f[0][0] = true; for (let i = 1; i <= n; ++i) { const x = nums[i - 1]; @@ -248,7 +258,11 @@ var canPartition = function (nums) { -### Solution 2 +### Solution 2: Dynamic Programming (Space Optimization) + +We notice that in Solution 1, $f[i][j]$ is only related to $f[i - 1][\cdot]$. Therefore, we can compress the two-dimensional array into a one-dimensional array. + +The time complexity is $O(n \times m)$, and the space complexity is $O(m)$. Where $n$ is the length of the array, and $m$ is half of the total sum of the array. diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.js b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.js index 8bed0fdbce431..b0838736551ab 100644 --- a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.js +++ b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.js @@ -9,9 +9,7 @@ var canPartition = function (nums) { } const n = nums.length; const m = s >> 1; - const f = Array(n + 1) - .fill(0) - .map(() => Array(m + 1).fill(false)); + const f = Array.from({ length: n + 1 }, () => Array(m + 1).fill(false)); f[0][0] = true; for (let i = 1; i <= n; ++i) { const x = nums[i - 1]; diff --git a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.ts b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.ts index 2a447d27d5503..d8ff4915400ba 100644 --- a/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.ts +++ b/solution/0400-0499/0416.Partition Equal Subset Sum/Solution.ts @@ -5,9 +5,7 @@ function canPartition(nums: number[]): boolean { } const n = nums.length; const m = s >> 1; - const f: boolean[][] = Array(n + 1) - .fill(0) - .map(() => Array(m + 1).fill(false)); + const f: boolean[][] = Array.from({ length: n + 1 }, () => Array(m + 1).fill(false)); f[0][0] = true; for (let i = 1; i <= n; ++i) { const x = nums[i - 1];