diff --git a/images/starcharts.svg b/images/starcharts.svg index 072aa331c10f2..c6c48c376ac73 100644 --- a/images/starcharts.svg +++ b/images/starcharts.svg @@ -1,4 +1,4 @@ - + \n2018-09-252019-04-212019-11-152020-06-102021-01-042021-07-312022-02-242022-09-202023-04-16Time2019-04-222019-11-172020-06-132021-01-082021-08-052022-03-032022-09-282023-04-25Time02800 \ No newline at end of file +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 945 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 946 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 14 +L 947 13 +L 947 13 +L 947 13 +L 947 13 +L 947 13 +L 947 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 948 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 949 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 13 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12 +L 950 12" style="stroke-width:2;stroke:rgba(129,199,239,1.0);fill:none"/> \ No newline at end of file diff --git a/lcci/16.17.Contiguous Sequence/README.md b/lcci/16.17.Contiguous Sequence/README.md index 25730ea7b5aee..08c366e8c1dc1 100644 --- a/lcci/16.17.Contiguous Sequence/README.md +++ b/lcci/16.17.Contiguous Sequence/README.md @@ -193,10 +193,29 @@ var maxSubArray = function (nums) { }; ``` -### **...** +### **PHP** +```php +class Solution { + /** + * @param Integer[] $nums + * @return Integer + */ + function maxSubArray($nums) { + $pre = 0; + $max = $nums[0]; + for ($i = 0; $i < count($nums); $i++) { + $pre = max($pre + $nums[$i], $nums[$i]); + $max = max($pre, $max); + } + return $max; + } +} ``` +### **...** + +``` ``` diff --git a/lcci/16.17.Contiguous Sequence/README_EN.md b/lcci/16.17.Contiguous Sequence/README_EN.md index 23b996e0bc31b..4c6463f5cd611 100644 --- a/lcci/16.17.Contiguous Sequence/README_EN.md +++ b/lcci/16.17.Contiguous Sequence/README_EN.md @@ -201,10 +201,29 @@ var maxSubArray = function (nums) { }; ``` -### **...** +### **PHP** +```php +class Solution { + /** + * @param Integer[] $nums + * @return Integer + */ + function maxSubArray($nums) { + $pre = 0; + $max = $nums[0]; + for ($i = 0; $i < count($nums); $i++) { + $pre = max($pre + $nums[$i], $nums[$i]); + $max = max($pre, $max); + } + return $max; + } +} ``` +### **...** + +``` ``` diff --git a/lcci/16.17.Contiguous Sequence/Solution.php b/lcci/16.17.Contiguous Sequence/Solution.php new file mode 100644 index 0000000000000..3b919e55cd8cc --- /dev/null +++ b/lcci/16.17.Contiguous Sequence/Solution.php @@ -0,0 +1,15 @@ +class Solution { + /** + * @param Integer[] $nums + * @return Integer + */ + function maxSubArray($nums) { + $pre = 0; + $max = $nums[0]; + for ($i = 0; $i < count($nums); $i++) { + $pre = max($pre + $nums[$i], $nums[$i]); + $max = max($pre, $max); + } + return $max; + } +} \ No newline at end of file diff --git "a/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo.png" "b/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo.png" index d728b510c3d17..8d36d700475de 100644 Binary files "a/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo.png" and "b/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo.png" differ diff --git "a/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo2.png" "b/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo2.png" index 642f0c4e401e3..b813d00162f1f 100644 Binary files "a/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo2.png" and "b/lcp/LCP 70. \346\262\231\345\234\260\346\262\273\347\220\206/images/demo2.png" differ diff --git "a/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805437-HQkyZS-image.png" "b/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805437-HQkyZS-image.png" index 92902d22aa294..7ee3824842a58 100644 Binary files "a/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805437-HQkyZS-image.png" and "b/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805437-HQkyZS-image.png" differ diff --git "a/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805536-zGfghe-image.png" "b/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805536-zGfghe-image.png" index 9cefe27943b96..fefe54cab4931 100644 Binary files "a/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805536-zGfghe-image.png" and "b/lcp/LCP 74. \346\234\200\345\274\272\347\245\235\347\246\217\345\212\233\345\234\272/images/1681805536-zGfghe-image.png" differ diff --git "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714676-gksEMT-image.png" "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714676-gksEMT-image.png" index 71d58414a1398..f6aa8d0ad921b 100644 Binary files "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714676-gksEMT-image.png" and "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714676-gksEMT-image.png" differ diff --git "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714693-LsxKAh-image.png" "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714693-LsxKAh-image.png" index 5d70f708cedf3..02a3add648170 100644 Binary files "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714693-LsxKAh-image.png" and "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681714693-LsxKAh-image.png" differ diff --git "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681789509-wTekFu-image.png" "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681789509-wTekFu-image.png" index 953f04aac5a53..2becf78145111 100644 Binary files "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681789509-wTekFu-image.png" and "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681789509-wTekFu-image.png" differ diff --git "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681800985-KrSdru-image.png" "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681800985-KrSdru-image.png" index e61fefcf285a5..86c65871ac84a 100644 Binary files "a/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681800985-KrSdru-image.png" and "b/lcp/LCP 75. \344\274\240\351\200\201\345\215\267\350\275\264/images/1681800985-KrSdru-image.png" differ diff --git "a/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714583-unbRox-image.png" "b/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714583-unbRox-image.png" index 52671aadd435d..4a20bd04319da 100644 Binary files "a/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714583-unbRox-image.png" and "b/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714583-unbRox-image.png" differ diff --git "a/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714596-beaOHK-image.png" "b/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714596-beaOHK-image.png" index 9ff5ecc3d1c87..aa9b281992b1d 100644 Binary files "a/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714596-beaOHK-image.png" and "b/lcp/LCP 76. \351\255\224\346\263\225\346\243\213\347\233\230/images/1681714596-beaOHK-image.png" differ diff --git a/package-lock.json b/package-lock.json index 95b37c50ebea0..a9947dee806a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1045,9 +1045,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" }, "semver-diff": { "version": "3.1.1", diff --git a/solution/0000-0099/0001.Two Sum/README_EN.md b/solution/0000-0099/0001.Two Sum/README_EN.md index 14ab392d7f602..ee2f36f3a7536 100644 --- a/solution/0000-0099/0001.Two Sum/README_EN.md +++ b/solution/0000-0099/0001.Two Sum/README_EN.md @@ -48,7 +48,7 @@ ## Solutions -**Approach 1: Hash Table** +**Solution 1: Hash Table** We can use the hash table $m$ to store the array value and the corresponding subscript. diff --git a/solution/0000-0099/0002.Add Two Numbers/README_EN.md b/solution/0000-0099/0002.Add Two Numbers/README_EN.md index 4a79775678c5f..01a8ba910bcdc 100644 --- a/solution/0000-0099/0002.Add Two Numbers/README_EN.md +++ b/solution/0000-0099/0002.Add Two Numbers/README_EN.md @@ -42,7 +42,7 @@ ## Solutions -**Approach 1: Simulation** +**Solution 1: Simulation** We traverse two linked lists $l_1$ and $l_2$ at the same time, and use the variable $carry$ to indicate whether there is a carry. diff --git a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md index 43c63a4702018..8dd59d3214139 100644 --- a/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md +++ b/solution/0000-0099/0003.Longest Substring Without Repeating Characters/README_EN.md @@ -42,7 +42,7 @@ Notice that the answer must be a substring, "pwke" is a subsequence an ## Solutions -**Approach 1: Two pointers + Hash Table** +**Solution 1: Two pointers + Hash Table** Define a hash table to record the characters in the current window. Let $i$ and $j$ represent the start and end positions of the non-repeating substring, respectively. The length of the longest non-repeating substring is recorded by `ans`. diff --git a/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md b/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md index 70968d34863b1..bb8a638c380f8 100644 --- a/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md +++ b/solution/0000-0099/0005.Longest Palindromic Substring/README_EN.md @@ -32,7 +32,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** Set $dp[i][j]$ to indicate whether the string $s[i..j]$ is a palindrome. @@ -41,7 +41,7 @@ Set $dp[i][j]$ to indicate whether the string $s[i..j]$ is a palindrome. The time complexity is $O(n^2)$ and the space complexity is $O(n^2)$. Where $n$ is the length of the string $s$. -**Approach 2: Enumerate the Palindrome Center** +**Solution 2: Enumerate the Palindrome Center** We can enumerate the palindrome center, spread to both sides, and find the longest palindrome. diff --git a/solution/0000-0099/0006.Zigzag Conversion/README_EN.md b/solution/0000-0099/0006.Zigzag Conversion/README_EN.md index fd5aa3fbb0611..87364a4700d3c 100644 --- a/solution/0000-0099/0006.Zigzag Conversion/README_EN.md +++ b/solution/0000-0099/0006.Zigzag Conversion/README_EN.md @@ -58,7 +58,7 @@ P I ## Solutions -**Approach 1: Simulation** +**Solution 1: Simulation** We use a 2D array $g$ to simulate the process of the $Z$-shaped arrangement, where $g[i][j]$ represents the character in the $i$th row and the $j$th column. Initially, $i=0$, and we also define a direction variable $k$, initially $k=-1$, which means up. diff --git a/solution/0000-0099/0007.Reverse Integer/README_EN.md b/solution/0000-0099/0007.Reverse Integer/README_EN.md index 19f15e5f2e23e..bfe92c30f17a9 100644 --- a/solution/0000-0099/0007.Reverse Integer/README_EN.md +++ b/solution/0000-0099/0007.Reverse Integer/README_EN.md @@ -39,7 +39,7 @@ ## Solutions -**Approach 1: Mathematical** +**Solution 1: Mathematical** Let $mi$ and $mx$ be $-2^{31}$ and $2^{31} - 1$ respectively. The reversed result $ans$ needs to satisfy $mi \le ans \le mx$. diff --git a/solution/0000-0099/0012.Integer to Roman/README_EN.md b/solution/0000-0099/0012.Integer to Roman/README_EN.md index 948bf10c88788..781d213951eea 100644 --- a/solution/0000-0099/0012.Integer to Roman/README_EN.md +++ b/solution/0000-0099/0012.Integer to Roman/README_EN.md @@ -62,7 +62,7 @@ M 1000 ## Solutions -**Approach 1: Greedy** +**Solution 1: Greedy** We can list all possible symbols $cs$ and corresponding values $vs$ first, then enumerate the value $vs[i]$ from large to small, and use the symbol $cs[i]$ as much as possible each time until the number $num$ becomes $0$. diff --git a/solution/0000-0099/0013.Roman to Integer/README_EN.md b/solution/0000-0099/0013.Roman to Integer/README_EN.md index 67d0f87518a65..e390cb35f64f1 100644 --- a/solution/0000-0099/0013.Roman to Integer/README_EN.md +++ b/solution/0000-0099/0013.Roman to Integer/README_EN.md @@ -64,7 +64,7 @@ M 1000 ## Solutions -**Approach 1: Hash table + simulation** +**Solution 1: Hash table + simulation** We first use a hash table $d$ to record the numerical value corresponding to each character, and then traverse the string $s$ from left to right. If the numerical value corresponding to the current character is less than the numerical value corresponding to the right character, subtract the numerical value corresponding to the current character, otherwise add the numerical value corresponding to the current character. diff --git a/solution/0000-0099/0014.Longest Common Prefix/README_EN.md b/solution/0000-0099/0014.Longest Common Prefix/README_EN.md index 177f14353d574..8cc10e8f6db36 100644 --- a/solution/0000-0099/0014.Longest Common Prefix/README_EN.md +++ b/solution/0000-0099/0014.Longest Common Prefix/README_EN.md @@ -35,7 +35,7 @@ ## Solutions -**Approach 1: Character Comparison** +**Solution 1: Character Comparison** We take the first string $strs[0]$ as the benchmark, and compare the $i$th character of the string after it with the $i$th character of $strs[0]$. If it is the same, continue to compare the next character, otherwise return the first $i$ characters of $strs[0]$. diff --git a/solution/0000-0099/0015.3Sum/README_EN.md b/solution/0000-0099/0015.3Sum/README_EN.md index cab7820d12c8b..b9d482998d153 100644 --- a/solution/0000-0099/0015.3Sum/README_EN.md +++ b/solution/0000-0099/0015.3Sum/README_EN.md @@ -48,7 +48,7 @@ Notice that the order of the output and the order of the triplets does not matte ## Solutions -**Approach 1: Sort + Two Pointers** +**Solution 1: Sort + Two Pointers** We notice that the problem does not require us to return the triplet in order, so we might as well sort the array first, which makes it easy to skip duplicate elements. diff --git a/solution/0000-0099/0018.4Sum/README_EN.md b/solution/0000-0099/0018.4Sum/README_EN.md index f7c18176413d9..a907e9c636013 100644 --- a/solution/0000-0099/0018.4Sum/README_EN.md +++ b/solution/0000-0099/0018.4Sum/README_EN.md @@ -40,7 +40,7 @@ ## Solutions -**Approach 1: Two Pointers** +**Solution 1: Two Pointers** Time complexity $O(n^3)$, Space complexity $O(\log n)$. diff --git a/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md b/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md index be8faf2bffda3..ab67c2014df84 100644 --- a/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md +++ b/solution/0000-0099/0024.Swap Nodes in Pairs/README_EN.md @@ -38,11 +38,11 @@ ## Solutions -**Approach 1: Iteration** +**Solution 1: Iteration** Time complexity $O(n)$, Space complexity $O(1)$. -**Approach 2: Recursion** +**Solution 2: Recursion** Time complexity $O(n)$, Space complexity $O(n)$. diff --git a/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md b/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md index 4f3439c1c331c..fe1f8c4137500 100644 --- a/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md +++ b/solution/0000-0099/0025.Reverse Nodes in k-Group/README_EN.md @@ -39,11 +39,11 @@ ## Solutions -**Approach 1: Iteration** +**Solution 1: Iteration** Time complexity $O(n)$, Space complexity $O(1)$. -**Approach 2: Recursion** +**Solution 2: Recursion** Time complexity $O(n)$, Space complexity $O(\log _k n)$. diff --git a/solution/0000-0099/0027.Remove Element/README_EN.md b/solution/0000-0099/0027.Remove Element/README_EN.md index 5b28df384f667..452534e3d3c6f 100644 --- a/solution/0000-0099/0027.Remove Element/README_EN.md +++ b/solution/0000-0099/0027.Remove Element/README_EN.md @@ -65,7 +65,7 @@ It does not matter what you leave beyond the returned k (hence they are undersco ## Solutions -**Approach 1: One Pass** +**Solution 1: One Pass** We use the variable $k$ to record the number of elements that are not equal to $val$. diff --git a/solution/0000-0099/0028.Find the Index of the First Occurrence in a String/README_EN.md b/solution/0000-0099/0028.Find the Index of the First Occurrence in a String/README_EN.md index dc934168d5b1c..d83a4b81c2db3 100644 --- a/solution/0000-0099/0028.Find the Index of the First Occurrence in a String/README_EN.md +++ b/solution/0000-0099/0028.Find the Index of the First Occurrence in a String/README_EN.md @@ -34,15 +34,15 @@ The first occurrence is at index 0, so we return 0. ## Solutions -**Approach 1: Traverse** +**Solution 1: Traverse** Time complexity $O((n-m) \times m)$, Space complexity $O(1)$. -**Approach 2: Rabin-Karp** +**Solution 2: Rabin-Karp** Time complexity $O(n+m)$, Space complexity $O(1)$. -**Approach 3: KMP** +**Solution 3: KMP** Time complexity $O(n+m)$, Space complexity $O(m)$. diff --git a/solution/0000-0099/0029.Divide Two Integers/README_EN.md b/solution/0000-0099/0029.Divide Two Integers/README_EN.md index e2867d7a64f14..df7d914f1ec35 100644 --- a/solution/0000-0099/0029.Divide Two Integers/README_EN.md +++ b/solution/0000-0099/0029.Divide Two Integers/README_EN.md @@ -39,7 +39,7 @@ ## Solutions -**Approach 1: Quick Power** +**Solution 1: Quick Power** Time complexity $O(\log a \times \log b)$, Space complexity $O(1)$. diff --git a/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md b/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md index b9eb527597628..ccc46cb66ba08 100644 --- a/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md +++ b/solution/0000-0099/0030.Substring with Concatenation of All Words/README_EN.md @@ -59,7 +59,7 @@ The substring starting at 12 is "thefoobar". It is the concatenation o ## Solutions -**Approach 1: Hash Table + Sliding Window** +**Solution 1: Hash Table + Sliding Window** We use a hash table $cnt$ to count the number of times each word in $words$ appears, and use a hash table $cnt1$ to count the number of times each word in the current sliding window appears. Let the length of the string $s$ be $m$, the number of words in the string array $words$ be $n$, and the length of each word be $k$. diff --git a/solution/0000-0099/0031.Next Permutation/README_EN.md b/solution/0000-0099/0031.Next Permutation/README_EN.md index 5d1f8e669a91b..17f412a0ff2d4 100644 --- a/solution/0000-0099/0031.Next Permutation/README_EN.md +++ b/solution/0000-0099/0031.Next Permutation/README_EN.md @@ -54,7 +54,7 @@ ## Solutions -**Approach 1: Two traversals** +**Solution 1: Two traversals** We first traverse the array from back to front and find the first position $i$ where $nums[i] \lt nums[i + 1]$. diff --git a/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md b/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md index ee2d42380fcd5..a425373846c01 100644 --- a/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md +++ b/solution/0000-0099/0032.Longest Valid Parentheses/README_EN.md @@ -40,7 +40,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** We define $f[i]$ to be the length of the longest valid parentheses that ends with $s[i-1]$, and the answer is $max(f[i])$. diff --git a/solution/0000-0099/0036.Valid Sudoku/README_EN.md b/solution/0000-0099/0036.Valid Sudoku/README_EN.md index 847d7070a9199..9e0642a1a740b 100644 --- a/solution/0000-0099/0036.Valid Sudoku/README_EN.md +++ b/solution/0000-0099/0036.Valid Sudoku/README_EN.md @@ -64,7 +64,7 @@ ## Solutions -**Approach 1: Traversal once** +**Solution 1: Traversal once** The valid sudoku satisfies the following three conditions: diff --git a/solution/0000-0099/0042.Trapping Rain Water/README_EN.md b/solution/0000-0099/0042.Trapping Rain Water/README_EN.md index c8b11a0c78b0f..a27d1ca42c7f9 100644 --- a/solution/0000-0099/0042.Trapping Rain Water/README_EN.md +++ b/solution/0000-0099/0042.Trapping Rain Water/README_EN.md @@ -33,7 +33,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** We define $left[i]$ as the height of the highest pillar to the left of and including the position with index $i$, and define $right[i]$ as the height of the highest pillar to the right of and including the position with index $i$. Then the amount of rain water that can be trapped at the position with index $i$ is $min(left[i], right[i]) - height[i]$. We traverse the array, calculate $left[i]$ and $right[i]$, and the answer is $\sum_{i=0}^{n-1} min(left[i], right[i]) - height[i]$. diff --git a/solution/0000-0099/0045.Jump Game II/README_EN.md b/solution/0000-0099/0045.Jump Game II/README_EN.md index 3a1d2c2301451..8987f32ff0ad5 100644 --- a/solution/0000-0099/0045.Jump Game II/README_EN.md +++ b/solution/0000-0099/0045.Jump Game II/README_EN.md @@ -42,7 +42,7 @@ ## Solutions -**Approach 1: Greedy** +**Solution 1: Greedy** We can use a variable $mx$ to record the furthest position that can be reached at the current position, and use a variable $last$ to record the last jump position, and use a variable $ans$ to record the number of jumps. diff --git a/solution/0000-0099/0048.Rotate Image/README_EN.md b/solution/0000-0099/0048.Rotate Image/README_EN.md index 374b401db563b..b6cdf343222cf 100644 --- a/solution/0000-0099/0048.Rotate Image/README_EN.md +++ b/solution/0000-0099/0048.Rotate Image/README_EN.md @@ -34,7 +34,7 @@ ## Solutions -**Approach 1: In-place** +**Solution 1: In-place** According to the requirements of the problem, we actually need to rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$. diff --git a/solution/0000-0099/0054.Spiral Matrix/README_EN.md b/solution/0000-0099/0054.Spiral Matrix/README_EN.md index 457e54323f6c6..edff9be09fa81 100644 --- a/solution/0000-0099/0054.Spiral Matrix/README_EN.md +++ b/solution/0000-0099/0054.Spiral Matrix/README_EN.md @@ -33,7 +33,7 @@ ## Solutions -**Approach 1: Simulation** +**Solution 1: Simulation** We use $i$ and $j$ to respectively represent the row and column of the current element being visited, and use $k$ to represent the current direction. We use an array or hash table $vis$ to record whether each element has been visited. After each element is visited, it is marked as visited, and then the current direction is moved forward one step. If the forward step goes out of bounds or has been visited, the direction is changed and continued. Move forward until the entire matrix is traversed. @@ -41,7 +41,7 @@ The time complexity is $O(m \times n)$ and the space complexity is $O(m \times n For the visited elements, we can also add a constant $300$ to their values, so we do not need an extra $vis$ array or hash table to record whether it has been visited, thus reducing the space complexity to $O(1)$. -**Approach 2: Layer-by-layer Simulation** +**Solution 2: Layer-by-layer Simulation** We can also traverse and store the matrix elements from the outside to the inside layer by layer. diff --git a/solution/0000-0099/0055.Jump Game/README_EN.md b/solution/0000-0099/0055.Jump Game/README_EN.md index d2fe58bfab356..e58ed5bae58c1 100644 --- a/solution/0000-0099/0055.Jump Game/README_EN.md +++ b/solution/0000-0099/0055.Jump Game/README_EN.md @@ -35,7 +35,7 @@ ## Solutions -**Approach 1: Greedy** +**Solution 1: Greedy** We use a variable $mx$ to maintain the farthest index that can be reached, initially $mx = 0$. diff --git a/solution/0000-0099/0058.Length of Last Word/README_EN.md b/solution/0000-0099/0058.Length of Last Word/README_EN.md index c33edc1be3332..e352c8abc6132 100644 --- a/solution/0000-0099/0058.Length of Last Word/README_EN.md +++ b/solution/0000-0099/0058.Length of Last Word/README_EN.md @@ -44,7 +44,7 @@ ## Solutions -**Approach 1: Reverse traversal + two pointers** +**Solution 1: Reverse traversal + two pointers** We start traversing from the end of the string $s$, finding the last character of the last word, which is not a space, and the subscript is $i$. Then continue to traverse forward to find the first space character, which is the character before the first character of the last word, and mark it as $j$. Then the length of the last word is $i - j$. diff --git a/solution/0000-0099/0071.Simplify Path/README_EN.md b/solution/0000-0099/0071.Simplify Path/README_EN.md index a7059c9ec0806..df39b7fb5ced2 100644 --- a/solution/0000-0099/0071.Simplify Path/README_EN.md +++ b/solution/0000-0099/0071.Simplify Path/README_EN.md @@ -55,7 +55,7 @@ ## Solutions -**Approach 1: Stack** +**Solution 1: Stack** We first split the path into a number of substrings split by `'/'`. Then, we traverse each substring and perform the following operations based on the content of the substring: diff --git a/solution/0000-0099/0073.Set Matrix Zeroes/README_EN.md b/solution/0000-0099/0073.Set Matrix Zeroes/README_EN.md index 52317224b832d..51c671af539a4 100644 --- a/solution/0000-0099/0073.Set Matrix Zeroes/README_EN.md +++ b/solution/0000-0099/0073.Set Matrix Zeroes/README_EN.md @@ -44,7 +44,7 @@ ## Solutions -**Approach 1: Array Mark** +**Solution 1: Array Mark** We use arrays `rows` and `cols` to mark the rows and columns to be cleared. @@ -52,7 +52,7 @@ Then traverse the matrix again, and clear the elements in the rows and columns m The time complexity is $O(m\times n)$, and the space complexity is $O(m+n)$. Where $m$ and $n$ are the number of rows and columns of the matrix respectively. -**Approach 2: Mark in Place** +**Solution 2: Mark in Place** In the first method, we use an additional array to mark the rows and columns to be cleared. In fact, we can also use the first row and first column of the matrix to mark them, without creating an additional array. diff --git a/solution/0000-0099/0076.Minimum Window Substring/README_EN.md b/solution/0000-0099/0076.Minimum Window Substring/README_EN.md index 7ae7ee48d9b2f..536761013aa50 100644 --- a/solution/0000-0099/0076.Minimum Window Substring/README_EN.md +++ b/solution/0000-0099/0076.Minimum Window Substring/README_EN.md @@ -49,7 +49,7 @@ Since the largest window of s only has one 'a', return empty string. ## Solutions -**Approach 1: Counting + Two Pointers** +**Solution 1: Counting + Two Pointers** We use a hash table or array $need$ to count the number of characters in string $t$, and use another hash table or array $window$ to count the number of characters in the sliding window. In addition, define two pointers $j$ and $i$ pointing to the left and right boundaries of the window, and the variable $cnt$ represents the number of characters in $t$ that are already included in the window. The variables $k$ and $mi$ represent the starting position and length of the minimum cover substring respectively. diff --git a/solution/0000-0099/0088.Merge Sorted Array/README_EN.md b/solution/0000-0099/0088.Merge Sorted Array/README_EN.md index 1980de8ce6f46..89716529b9a7c 100644 --- a/solution/0000-0099/0088.Merge Sorted Array/README_EN.md +++ b/solution/0000-0099/0088.Merge Sorted Array/README_EN.md @@ -55,7 +55,7 @@ Note that because m = 0, there are no elements in nums1. The 0 is only there to ## Solutions -**Approach 1: Two Pointers** +**Solution 1: Two Pointers** We use two pointers $i$ and $j$ pointing to the end of two arrays, and a pointer $k$ pointing to the end of the merged array. diff --git a/solution/0100-0199/0121.Best Time to Buy and Sell Stock/README_EN.md b/solution/0100-0199/0121.Best Time to Buy and Sell Stock/README_EN.md index e3a92ac6eef19..0d7dadd54b9c8 100644 --- a/solution/0100-0199/0121.Best Time to Buy and Sell Stock/README_EN.md +++ b/solution/0100-0199/0121.Best Time to Buy and Sell Stock/README_EN.md @@ -38,7 +38,7 @@ Note that buying on day 2 and selling on day 1 is not allowed because you must b ## Solutions -**Approach 1: Enumerate + Maintain the Minimum Value of the Prefix** +**Solution 1: Enumerate + Maintain the Minimum Value of the Prefix** We can enumerate each element of the array $nums$ as the selling price. Then we need to find a minimum value in front of it as the purchase price to maximize the profit. diff --git a/solution/0100-0199/0122.Best Time to Buy and Sell Stock II/README_EN.md b/solution/0100-0199/0122.Best Time to Buy and Sell Stock II/README_EN.md index fca698af01266..ab08895345f81 100644 --- a/solution/0100-0199/0122.Best Time to Buy and Sell Stock II/README_EN.md +++ b/solution/0100-0199/0122.Best Time to Buy and Sell Stock II/README_EN.md @@ -48,13 +48,13 @@ Total profit is 4. ## Solutions -**Approach 1: Greedy** +**Solution 1: Greedy** From the second day, if the stock price on that day is greater than the previous day, buy it on the previous day and sell it on that day to get a profit. If the stock price on that day is less than the previous day, do not buy it or sell it. That is to say, all the rising trading days are bought and sold, and all the falling trading days are not bought or sold, and the final profit is the maximum. The time complexity is $O(n)$, where $n$ is the length of the array `prices`. The space complexity is $O(1)$. -**Approach 2: Dynamic Programming** +**Solution 2: Dynamic Programming** Let $f[i][j]$ represent the maximum profit after the $i$th day of trading, where $j$ represents whether the current stock is held, and $j=0$ when the stock is held, and $j=1$ when the stock is not held. The initial state is $f[0][0]=-prices[0]$, and all other states are $0$. @@ -75,9 +75,9 @@ The final answer is $f[n-1][1]$, where $n$ is the length of the array `prices`. The time complexity is $O(n)$ and the space complexity is $O(n)$. $n$ is the length of the array `prices`. -**Approach 3: Dynamic Programming (space optimization)** +**Solution 3: Dynamic Programming (space optimization)** -We can find that in approach 2, the state of the $i$th day only depends on the state of the $i-1$th day, so we can only use two variables to maintain the state of the $i-1$th day. Therefore, the space complexity can be optimized to $O(1)$. +We can find that in Solution 2, the state of the $i$th day only depends on the state of the $i-1$th day, so we can only use two variables to maintain the state of the $i-1$th day. Therefore, the space complexity can be optimized to $O(1)$. Time complexity $O(n)$, where $n$ is the length of the array `prices`. Space complexity $O(1)$. diff --git a/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md b/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md index 2e98a9229ede8..9e86ad4d799af 100644 --- a/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md +++ b/solution/0100-0199/0128.Longest Consecutive Sequence/README_EN.md @@ -34,7 +34,7 @@ ## Solutions -**Approach 1: Sorting** +**Solution 1: Sorting** First, we sort the array, and use a variable $t$ to record the length of the current continuous sequence, and use a variable $ans$ to record the length of the longest continuous sequence. @@ -48,7 +48,7 @@ Finally, we return the answer $ans$. Time complexity $O(n \times \log n)$, space complexity $O(\log n)$, where $n$ is the length of the array. -**Approach 2: Hash Table** +**Solution 2: Hash Table** We use a hash table to store all the elements in the array, and then we traverse the array to find the longest continuous sequence for each element $x$. If the predecessor of the current element $x-1$ is not in the hash table, we use the current element as the starting point, and keep trying to match $x+1, x+2, x+3, \dots$ until we cannot match, the matching length at this time is the length of the longest continuous sequence starting from $x$, so we update the answer. diff --git a/solution/0100-0199/0135.Candy/README_EN.md b/solution/0100-0199/0135.Candy/README_EN.md index bea65137e9d12..03198acfef1c1 100644 --- a/solution/0100-0199/0135.Candy/README_EN.md +++ b/solution/0100-0199/0135.Candy/README_EN.md @@ -44,7 +44,7 @@ The third child gets 1 candy because it satisfies the above two conditions. ## Solutions -**Approach 1: Two traversals** +**Solution 1: Two traversals** We initialize two arrays $left$ and $right$, where $left[i]$ represents the minimum number of candies the current child should get when the current child's score is higher than the left child's score, and $right[i]$ represents the minimum number of candies the current child should get when the current child's score is higher than the right child's score. Initially, $left[i]=1$, $right[i]=1$. diff --git a/solution/0100-0199/0151.Reverse Words in a String/README_EN.md b/solution/0100-0199/0151.Reverse Words in a String/README_EN.md index 4858f2c968e46..3b559fed6cbe0 100644 --- a/solution/0100-0199/0151.Reverse Words in a String/README_EN.md +++ b/solution/0100-0199/0151.Reverse Words in a String/README_EN.md @@ -50,13 +50,13 @@ ## Solutions -**Approach 1: Use Language Built-in Functions** +**Solution 1: Use Language Built-in Functions** We split the string into a list of strings by spaces, then reverse the list, and finally join the list into a string separated by spaces. Time complexity $O(n)$, space complexity $O(n)$, where $n$ is the length of the string. -**Approach 2: Two Pointers** +**Solution 2: Two Pointers** We can use two pointers $i$ and $j$, each time we find a word, add it to the result list, then reverse the result list, and finally join the list into a string. diff --git a/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md b/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md index 5f0cbddd84462..712184dac5bf7 100644 --- a/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md +++ b/solution/0100-0199/0167.Two Sum II - Input Array Is Sorted/README_EN.md @@ -50,13 +50,13 @@ ## Solutions -**Approach 1: Binary Search** +**Solution 1: Binary Search** Note that the array is sorted in non-decreasing order, so for each `numbers[i]`, we can find the position of `target - numbers[i]` by binary search, and return $[i + 1, j + 1]$ if it exists. The time complexity is $O(n \times \log n)$, where $n$ is the length of the array `numbers`. The space complexity is $O(1)$. -**Approach 2: Two Pointers** +**Solution 2: Two Pointers** We define two pointers $i$ and $j$, which point to the first element and the last element of the array respectively. Each time we calculate $numbers[i] + numbers[j]$. If the sum is equal to the target value, return $[i + 1, j + 1]$ directly. If the sum is less than the target value, move $i$ to the right by one position, and if the sum is greater than the target value, move $j$ to the left by one position. diff --git a/solution/0100-0199/0169.Majority Element/README_EN.md b/solution/0100-0199/0169.Majority Element/README_EN.md index 1656a2d2d2e57..e4544ba7bdb9b 100644 --- a/solution/0100-0199/0169.Majority Element/README_EN.md +++ b/solution/0100-0199/0169.Majority Element/README_EN.md @@ -30,7 +30,7 @@ ## Solutions -**Approach 1: Moore Voting Algorithm** +**Solution 1: Moore Voting Algorithm** The basic steps of the Moore voting algorithm are as follows: diff --git a/solution/0100-0199/0187.Repeated DNA Sequences/README_EN.md b/solution/0100-0199/0187.Repeated DNA Sequences/README_EN.md index 4e4c157a93d6b..02731857a6981 100644 --- a/solution/0100-0199/0187.Repeated DNA Sequences/README_EN.md +++ b/solution/0100-0199/0187.Repeated DNA Sequences/README_EN.md @@ -32,11 +32,11 @@ ## Solutions -**Approach 1: HashTable** +**Solution 1: HashTable** Time complexity $O(n \times 10)$, Space complexity $O(n)$. -**Approach 2: Rabin-Karp** +**Solution 2: Rabin-Karp** Time complexity $O(n)$, Space complexity $O(n)$. diff --git a/solution/0100-0199/0189.Rotate Array/README_EN.md b/solution/0100-0199/0189.Rotate Array/README_EN.md index c71d80120ce6f..ed2c4a7e4b64b 100644 --- a/solution/0100-0199/0189.Rotate Array/README_EN.md +++ b/solution/0100-0199/0189.Rotate Array/README_EN.md @@ -47,7 +47,7 @@ rotate 2 steps to the right: [3,99,-1,-100] ## Solutions -**Approach 1: Reverse three times** +**Solution 1: Reverse three times** We can assume the length of the array is $n$ and calculate the actual number of steps needed by taking the module of $k$ and $n$, which is $k \bmod n$. diff --git a/solution/0200-0299/0205.Isomorphic Strings/README_EN.md b/solution/0200-0299/0205.Isomorphic Strings/README_EN.md index bbbe4f0d72e7b..4b9d2d99dfedf 100644 --- a/solution/0200-0299/0205.Isomorphic Strings/README_EN.md +++ b/solution/0200-0299/0205.Isomorphic Strings/README_EN.md @@ -32,7 +32,7 @@ ## Solutions -**Approach 1: Hash Table or Array** +**Solution 1: Hash Table or Array** We can use two hash tables or arrays $d_1$ and $d_2$ to record the character mapping relationship between $s$ and $t$. diff --git a/solution/0200-0299/0219.Contains Duplicate II/README_EN.md b/solution/0200-0299/0219.Contains Duplicate II/README_EN.md index 4c9e2df08e889..08a9840aefc66 100644 --- a/solution/0200-0299/0219.Contains Duplicate II/README_EN.md +++ b/solution/0200-0299/0219.Contains Duplicate II/README_EN.md @@ -39,7 +39,7 @@ ## Solutions -**Approach 1: Hash Table** +**Solution 1: Hash Table** We use a hash table $d$ to store the nearest index of the number it has visited. diff --git a/solution/0200-0299/0228.Summary Ranges/README_EN.md b/solution/0200-0299/0228.Summary Ranges/README_EN.md index 7c4cc62185baf..a31a93ee0638b 100644 --- a/solution/0200-0299/0228.Summary Ranges/README_EN.md +++ b/solution/0200-0299/0228.Summary Ranges/README_EN.md @@ -53,7 +53,7 @@ ## Solutions -**Approach 1: Two Pointers** +**Solution 1: Two Pointers** We can use two pointers $i$ and $j$ to find the left and right endpoints of each interval. diff --git a/solution/0200-0299/0237.Delete Node in a Linked List/README_EN.md b/solution/0200-0299/0237.Delete Node in a Linked List/README_EN.md index 32bcba7e17aee..a71d778a561bf 100644 --- a/solution/0200-0299/0237.Delete Node in a Linked List/README_EN.md +++ b/solution/0200-0299/0237.Delete Node in a Linked List/README_EN.md @@ -56,7 +56,7 @@ ## Solutions -**Approach 1: Node assignment** +**Solution 1: Node assignment** We can replace the value of the current node with the value of the next node, and then delete the next node. This can achieve the purpose of deleting the current node. diff --git a/solution/0200-0299/0238.Product of Array Except Self/README_EN.md b/solution/0200-0299/0238.Product of Array Except Self/README_EN.md index c8404b15c062f..df54a2193619e 100644 --- a/solution/0200-0299/0238.Product of Array Except Self/README_EN.md +++ b/solution/0200-0299/0238.Product of Array Except Self/README_EN.md @@ -32,7 +32,7 @@ ## Solutions -**Approach 1: Two Passes** +**Solution 1: Two Passes** We define two variables $left$ and $right$, which represent the product of all elements to the left and right of the current element respectively. Initially, $left=1$, $right=1$. Define an answer array $ans$ of length $n$. diff --git a/solution/0200-0299/0242.Valid Anagram/README_EN.md b/solution/0200-0299/0242.Valid Anagram/README_EN.md index 295987089deb7..0531db2495957 100644 --- a/solution/0200-0299/0242.Valid Anagram/README_EN.md +++ b/solution/0200-0299/0242.Valid Anagram/README_EN.md @@ -29,7 +29,7 @@ ## Solutions -**Approach 1: Counting** +**Solution 1: Counting** We first determine whether the length of the two strings is equal. If they are not equal, the characters in the two strings must be different, so return `false`. diff --git a/solution/0200-0299/0274.H-Index/README_EN.md b/solution/0200-0299/0274.H-Index/README_EN.md index 84076b081c855..a46a595c63ea9 100644 --- a/solution/0200-0299/0274.H-Index/README_EN.md +++ b/solution/0200-0299/0274.H-Index/README_EN.md @@ -36,13 +36,13 @@ Since the researcher has 3 papers with at least 3 citations each and the remaini ## Solutions -**Approach 1: Sorting** +**Solution 1: Sorting** We can sort the array `citations` in descending order. Then we enumerate the value $h$ from large to small, if there is an $h$ value satisfying $citations[h-1] \geq h$, it means that there are at least $h$ papers that have been cited at least $h$ times, just return $h$ directly. If we cannot find such an $h$ value, it means that all the papers have not been cited, return $0$. Time complexity $O(n \times \log n)$, space complexity $O(\log n)$. Here $n$ is the length of the array `citations`. -**Approach 2: Counting + Sum** +**Solution 2: Counting + Sum** We can use an array $cnt$ of length $n+1$, where $cnt[i]$ represents the number of papers with the reference count of $i$. We traverse the array `citations` and treat the papers with the reference count greater than $n$ as papers with a reference count of $n$. Then we use the reference count as the index and add $1$ to the corresponding element of $cnt$ for each paper. In this way, we have counted the number of papers for each reference count. @@ -50,7 +50,7 @@ Then we enumerate the value $h$ from large to small, and add the element value o Time complexity $O(n)$, space complexity $O(n)$. Here $n$ is the length of the array `citations`. -**Approach 3: Binary Search** +**Solution 3: Binary Search** We notice that if there is a $h$ value that satisfies at least $h$ papers are cited at least $h$ times, then for any $h' -动态规划。 +**方法一:动态规划** -设 up 表示以前 i 个元素中的某一个元素结尾的最长上升摆动序列的长度,down 表示以前 i 个元素中的某一个元素结尾的最长下降摆动序列的长度。初始 `up = 1`, `down = 1`。 +我们定义 $f[i][0]$ 表示以第 $i$ 个元素结尾,且最后两个元素的差为负数的最长摆动序列的长度,定义 $f[i][1]$ 表示以第 $i$ 个元素结尾,且最后两个元素的差为正数的最长摆动序列的长度。初始时 $f[0][0]=1$, $f[0][1]=1$。 -从数组下标 1 开始遍历: +我们可以得到状态转移方程: -- 若 `nums[i] > nums[i - 1]`,则需要更新最长上升摆动序列的长度:`up = max(up, down + 1)` -- 若 `nums[i] < nums[i - 1]`,则需要更新最长下降摆动序列的长度:`down = max(down, up + 1)` +$$ +f[i][0] = \max(f[j][1] + 1), \quad nums[i] < nums[j], j \in [0, i - 1] +$$ -最后返回 `max(up, down)` 即可。 +$$ +f[i][1] = \max(f[j][0] + 1), \quad nums[i] > nums[j], j \in [0, i - 1] +$$ + +答案为 $f[i][0]$ 和 $f[i][1]$ 中的最大值。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。 + +**方法二:动态规划(优化)** + +我们定义变量 $f$ 和 $g$ 分别表示当前最后两个元素的差为负数和正数的最长摆动序列的长度。初始时 $f = 1$, $g = 1$。 + +遍历数组 $nums[1,..]$,如果当前元素 $nums[i]$ 大于前一个元素 $nums[i - 1]$,则 $f = \max(f, g + 1)$,否则如果当前元素 $nums[i]$ 小于前一个元素 $nums[i - 1]$,则 $g = \max(g, f + 1)$。 + +遍历结束后,将 $f$ 和 $g$ 中的最大值作为答案返回。 + +时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组的长度。 @@ -82,13 +99,32 @@ ```python class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: - up = down = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i - 1]: - up = max(up, down + 1) - elif nums[i] < nums[i - 1]: - down = max(down, up + 1) - return max(up, down) + n = len(nums) + f = [[1] * 2 for _ in range(n)] + ans = 1 + for i in range(1, n): + for j in range(i): + d = nums[i] - nums[j] + if d == 0: + continue + if d < 0: + f[i][0] = max(f[i][0], f[j][1] + 1) + if d > 0: + f[i][1] = max(f[i][1], f[j][0] + 1) + ans = max(ans, *f[i]) + return ans +``` + +```python +class Solution: + def wiggleMaxLength(self, nums: List[int]) -> int: + f = g = 1 + for a, b in pairwise(nums): + if a < b: + f = max(f, g + 1) + if a > b: + g = max(g, f + 1) + return max(f, g) ``` ### **Java** @@ -98,35 +134,46 @@ class Solution: ```java class Solution { public int wiggleMaxLength(int[] nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.length; ++i) { - if (nums[i] > nums[i - 1]) { - up = Math.max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = Math.max(down, up + 1); + int n = nums.length; + int[][] f = new int[n][2]; + int ans = 1; + f[0][0] = 1; + f[0][1] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + int d = nums[i] - nums[j]; + if (d == 0) { + continue; + } + if (d < 0) { + f[i][0] = Math.max(f[i][0], f[j][1] + 1); + } + if (d > 0) { + f[i][1] = Math.max(f[i][1], f[j][0] + 1); + } } + ans = Math.max(ans, Math.max(f[i][0], f[i][1])); } - return Math.max(up, down); + return ans; } } ``` -### **TypeScript** - -```ts -function wiggleMaxLength(nums: number[]): number { - let up = 1, - down = 1; - for (let i = 1; i < nums.length; ++i) { - let prev = nums[i - 1], - cur = nums[i]; - if (cur > prev) { - up = Math.max(up, down + 1); - } else if (cur < prev) { - down = Math.max(down, up + 1); +```java +class Solution { + public int wiggleMaxLength(int[] nums) { + int f = 1, g = 1; + for (int i = 1; i < nums.length; ++i) { + int d = nums[i] - nums[i - 1]; + if (d < 0) { + f = Math.max(f, g + 1); + } + if (d > 0) { + g = Math.max(g, f + 1); + } } + return Math.max(f, g); } - return Math.max(up, down); } ``` @@ -136,15 +183,47 @@ function wiggleMaxLength(nums: number[]): number { class Solution { public: int wiggleMaxLength(vector& nums) { - int up = 1, down = 1; + int n = nums.size(); + int f[n][2]; + memset(f, 0, sizeof(f)); + int ans = 1; + f[0][0] = 1; + f[0][1] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + int d = nums[i] - nums[j]; + if (d == 0) { + continue; + } + if (d < 0) { + f[i][0] = max(f[i][0], f[j][1] + 1); + } + if (d > 0) { + f[i][1] = max(f[i][1], f[j][0] + 1); + } + } + ans = max({ans, f[i][0], f[i][1]}); + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + int wiggleMaxLength(vector& nums) { + int f = 1, g = 1; for (int i = 1; i < nums.size(); ++i) { - if (nums[i] > nums[i - 1]) { - up = max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = max(down, up + 1); + int d = nums[i] - nums[i - 1]; + if (d < 0) { + f = max(f, g + 1); + } + if (d > 0) { + g = max(g, f + 1); } } - return max(up, down); + return max(f, g); } }; ``` @@ -153,15 +232,46 @@ public: ```go func wiggleMaxLength(nums []int) int { - up, down := 1, 1 - for i := 1; i < len(nums); i++ { - if nums[i] > nums[i-1] { - up = max(up, down+1) - } else if nums[i] < nums[i-1] { - down = max(down, up+1) + n := len(nums) + f := make([][2]int, n) + f[0][0], f[0][1] = 1, 1 + ans := 1 + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + d := nums[i] - nums[j] + if d < 0 { + f[i][0] = max(f[i][0], f[j][1]+1) + } + if d > 0 { + f[i][1] = max(f[i][1], f[j][0]+1) + } + } + ans = max(ans, max(f[i][0], f[i][1])) + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +```go +func wiggleMaxLength(nums []int) int { + f, g := 1, 1 + for i, x := range nums[1:] { + d := x - nums[i] + if d < 0 { + f = max(f, g+1) + } + if d > 0 { + g = max(g, f+1) } } - return max(up, down) + return max(f, g) } func max(a, b int) int { @@ -172,6 +282,25 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function wiggleMaxLength(nums: number[]): number { + let up = 1, + down = 1; + for (let i = 1; i < nums.length; ++i) { + let prev = nums[i - 1], + cur = nums[i]; + if (cur > prev) { + up = Math.max(up, down + 1); + } else if (cur < prev) { + down = Math.max(down, up + 1); + } + } + return Math.max(up, down); +} +``` + ### **...** ``` diff --git a/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md b/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md index e7e26ec1f3178..71b221f8dddf4 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md +++ b/solution/0300-0399/0376.Wiggle Subsequence/README_EN.md @@ -62,13 +62,32 @@ Dynamic programming. ```python class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: - up = down = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i - 1]: - up = max(up, down + 1) - elif nums[i] < nums[i - 1]: - down = max(down, up + 1) - return max(up, down) + n = len(nums) + f = [[1] * 2 for _ in range(n)] + ans = 1 + for i in range(1, n): + for j in range(i): + d = nums[i] - nums[j] + if d == 0: + continue + if d < 0: + f[i][0] = max(f[i][0], f[j][1] + 1) + if d > 0: + f[i][1] = max(f[i][1], f[j][0] + 1) + ans = max(ans, *f[i]) + return ans +``` + +```python +class Solution: + def wiggleMaxLength(self, nums: List[int]) -> int: + f = g = 1 + for a, b in pairwise(nums): + if a < b: + f = max(f, g + 1) + if a > b: + g = max(g, f + 1) + return max(f, g) ``` ### **Java** @@ -76,35 +95,46 @@ class Solution: ```java class Solution { public int wiggleMaxLength(int[] nums) { - int up = 1, down = 1; - for (int i = 1; i < nums.length; ++i) { - if (nums[i] > nums[i - 1]) { - up = Math.max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = Math.max(down, up + 1); + int n = nums.length; + int[][] f = new int[n][2]; + int ans = 1; + f[0][0] = 1; + f[0][1] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + int d = nums[i] - nums[j]; + if (d == 0) { + continue; + } + if (d < 0) { + f[i][0] = Math.max(f[i][0], f[j][1] + 1); + } + if (d > 0) { + f[i][1] = Math.max(f[i][1], f[j][0] + 1); + } } + ans = Math.max(ans, Math.max(f[i][0], f[i][1])); } - return Math.max(up, down); + return ans; } } ``` -### **TypeScript** - -```ts -function wiggleMaxLength(nums: number[]): number { - let up = 1, - down = 1; - for (let i = 1; i < nums.length; ++i) { - let prev = nums[i - 1], - cur = nums[i]; - if (cur > prev) { - up = Math.max(up, down + 1); - } else if (cur < prev) { - down = Math.max(down, up + 1); +```java +class Solution { + public int wiggleMaxLength(int[] nums) { + int f = 1, g = 1; + for (int i = 1; i < nums.length; ++i) { + int d = nums[i] - nums[i - 1]; + if (d < 0) { + f = Math.max(f, g + 1); + } + if (d > 0) { + g = Math.max(g, f + 1); + } } + return Math.max(f, g); } - return Math.max(up, down); } ``` @@ -114,15 +144,47 @@ function wiggleMaxLength(nums: number[]): number { class Solution { public: int wiggleMaxLength(vector& nums) { - int up = 1, down = 1; + int n = nums.size(); + int f[n][2]; + memset(f, 0, sizeof(f)); + int ans = 1; + f[0][0] = 1; + f[0][1] = 1; + for (int i = 1; i < n; ++i) { + for (int j = 0; j < i; ++j) { + int d = nums[i] - nums[j]; + if (d == 0) { + continue; + } + if (d < 0) { + f[i][0] = max(f[i][0], f[j][1] + 1); + } + if (d > 0) { + f[i][1] = max(f[i][1], f[j][0] + 1); + } + } + ans = max({ans, f[i][0], f[i][1]}); + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + int wiggleMaxLength(vector& nums) { + int f = 1, g = 1; for (int i = 1; i < nums.size(); ++i) { - if (nums[i] > nums[i - 1]) { - up = max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = max(down, up + 1); + int d = nums[i] - nums[i - 1]; + if (d < 0) { + f = max(f, g + 1); + } + if (d > 0) { + g = max(g, f + 1); } } - return max(up, down); + return max(f, g); } }; ``` @@ -131,15 +193,46 @@ public: ```go func wiggleMaxLength(nums []int) int { - up, down := 1, 1 - for i := 1; i < len(nums); i++ { - if nums[i] > nums[i-1] { - up = max(up, down+1) - } else if nums[i] < nums[i-1] { - down = max(down, up+1) + n := len(nums) + f := make([][2]int, n) + f[0][0], f[0][1] = 1, 1 + ans := 1 + for i := 1; i < n; i++ { + for j := 0; j < i; j++ { + d := nums[i] - nums[j] + if d < 0 { + f[i][0] = max(f[i][0], f[j][1]+1) + } + if d > 0 { + f[i][1] = max(f[i][1], f[j][0]+1) + } + } + ans = max(ans, max(f[i][0], f[i][1])) + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +```go +func wiggleMaxLength(nums []int) int { + f, g := 1, 1 + for i, x := range nums[1:] { + d := x - nums[i] + if d < 0 { + f = max(f, g+1) + } + if d > 0 { + g = max(g, f+1) } } - return max(up, down) + return max(f, g) } func max(a, b int) int { @@ -150,6 +243,25 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function wiggleMaxLength(nums: number[]): number { + let up = 1, + down = 1; + for (let i = 1; i < nums.length; ++i) { + let prev = nums[i - 1], + cur = nums[i]; + if (cur > prev) { + up = Math.max(up, down + 1); + } else if (cur < prev) { + down = Math.max(down, up + 1); + } + } + return Math.max(up, down); +} +``` + ### **...** ``` diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp b/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp index c4cc9f807f91d..128d9d00cb730 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.cpp @@ -1,14 +1,16 @@ class Solution { public: int wiggleMaxLength(vector& nums) { - int up = 1, down = 1; + int f = 1, g = 1; for (int i = 1; i < nums.size(); ++i) { - if (nums[i] > nums[i - 1]) { - up = max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = max(down, up + 1); + int d = nums[i] - nums[i - 1]; + if (d < 0) { + f = max(f, g + 1); + } + if (d > 0) { + g = max(g, f + 1); } } - return max(up, down); + return max(f, g); } }; \ No newline at end of file diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.go b/solution/0300-0399/0376.Wiggle Subsequence/Solution.go index 6f919e2a47801..b35c909195e8f 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.go +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.go @@ -1,13 +1,15 @@ func wiggleMaxLength(nums []int) int { - up, down := 1, 1 - for i := 1; i < len(nums); i++ { - if nums[i] > nums[i-1] { - up = max(up, down+1) - } else if nums[i] < nums[i-1] { - down = max(down, up+1) + f, g := 1, 1 + for i, x := range nums[1:] { + d := x - nums[i] + if d < 0 { + f = max(f, g+1) + } + if d > 0 { + g = max(g, f+1) } } - return max(up, down) + return max(f, g) } func max(a, b int) int { diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.java b/solution/0300-0399/0376.Wiggle Subsequence/Solution.java index c344740ff32a5..645f43660f001 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.java +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.java @@ -1,13 +1,15 @@ class Solution { public int wiggleMaxLength(int[] nums) { - int up = 1, down = 1; + int f = 1, g = 1; for (int i = 1; i < nums.length; ++i) { - if (nums[i] > nums[i - 1]) { - up = Math.max(up, down + 1); - } else if (nums[i] < nums[i - 1]) { - down = Math.max(down, up + 1); + int d = nums[i] - nums[i - 1]; + if (d < 0) { + f = Math.max(f, g + 1); + } + if (d > 0) { + g = Math.max(g, f + 1); } } - return Math.max(up, down); + return Math.max(f, g); } } \ No newline at end of file diff --git a/solution/0300-0399/0376.Wiggle Subsequence/Solution.py b/solution/0300-0399/0376.Wiggle Subsequence/Solution.py index 175ef70797925..c853cf62e899f 100644 --- a/solution/0300-0399/0376.Wiggle Subsequence/Solution.py +++ b/solution/0300-0399/0376.Wiggle Subsequence/Solution.py @@ -1,9 +1,9 @@ class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: - up = down = 1 - for i in range(1, len(nums)): - if nums[i] > nums[i - 1]: - up = max(up, down + 1) - elif nums[i] < nums[i - 1]: - down = max(down, up + 1) - return max(up, down) + f = g = 1 + for a, b in pairwise(nums): + if a < b: + f = max(f, g + 1) + if a > b: + g = max(g, f + 1) + return max(f, g) diff --git a/solution/0300-0399/0380.Insert Delete GetRandom O(1)/README_EN.md b/solution/0300-0399/0380.Insert Delete GetRandom O(1)/README_EN.md index ad4a1e011504d..b3b796c4c022e 100644 --- a/solution/0300-0399/0380.Insert Delete GetRandom O(1)/README_EN.md +++ b/solution/0300-0399/0380.Insert Delete GetRandom O(1)/README_EN.md @@ -47,7 +47,7 @@ randomizedSet.getRandom(); // Since 2 is the only number in the set, getRandom() ## Solutions -**Approach 1: Hash Table + Dynamic List** +**Solution 1: Hash Table + Dynamic List** We define a dynamic list $q$ to store the elements in the set, and a hash table $d$ to store the index of each element in $q$. diff --git a/solution/0300-0399/0383.Ransom Note/README_EN.md b/solution/0300-0399/0383.Ransom Note/README_EN.md index d878f4d5df61f..9a193232909c6 100644 --- a/solution/0300-0399/0383.Ransom Note/README_EN.md +++ b/solution/0300-0399/0383.Ransom Note/README_EN.md @@ -29,7 +29,7 @@ ## Solutions -**Approach 1: Hash Table or Array** +**Solution 1: Hash Table or Array** We can use a hash table or an array $cnt$ of length $26$ to record the number of times each character appears in the string `magazine`. Then traverse the string `ransomNote`, for each character $c$ in it, we decrease the number of $c$ by $1$ in $cnt$. If the number of $c$ is less than $0$ after the decrease, it means that the number of $c$ in `magazine` is not enough, so it cannot be composed of `ransomNote`, just return $false$. diff --git a/solution/0300-0399/0385.Mini Parser/README_EN.md b/solution/0300-0399/0385.Mini Parser/README_EN.md index 4d3dce1c083e6..bed648655b342 100644 --- a/solution/0300-0399/0385.Mini Parser/README_EN.md +++ b/solution/0300-0399/0385.Mini Parser/README_EN.md @@ -42,7 +42,7 @@ ## Solutions -**Approach 1: Recursion** +**Solution 1: Recursion** We first judge whether the string $s$ is empty or an empty list. If so, simply return an empty `NestedInteger`. If $s$ is an integer, we simply return a `NestedInteger` containing this integer. Otherwise, we traverse the string $s$ from left to right. If the current depth is $0$ and we encounter a comma or the end of the string $s$, we take a substring and recursively call the function to parse the substring and add the return value to the list. Otherwise, if the current encounter is a left parenthesis, we increase the depth by $1$ and continue to traverse. If we encounter a right parenthesis, we decrease the depth by $1$ and continue to traverse. @@ -50,7 +50,7 @@ After the traversal is over, return the answer. The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the string $s$. -**Approach 2: Stack** +**Solution 2: Stack** We can use a stack to simulate the recursive process. diff --git a/solution/0300-0399/0392.Is Subsequence/README_EN.md b/solution/0300-0399/0392.Is Subsequence/README_EN.md index 7ffa1b17a627d..c05d8652b7ba3 100644 --- a/solution/0300-0399/0392.Is Subsequence/README_EN.md +++ b/solution/0300-0399/0392.Is Subsequence/README_EN.md @@ -30,7 +30,7 @@ ## Solutions -**Approach 1: Two Pointers** +**Solution 1: Two Pointers** We define two pointers $i$ and $j$ to point to the initial position of the string $s$ and $t$ respectively. Each time we compare the two characters pointed to by the two pointers, if they are the same, both pointers move right at the same time; if they are not the same, only $j$ moves right. When the pointer $i$ moves to the end of the string $s$, it means that $s$ is the subsequence of $t$. diff --git a/solution/0400-0499/0402.Remove K Digits/README_EN.md b/solution/0400-0499/0402.Remove K Digits/README_EN.md index 7f35c7e697cdb..5443e8896d5c7 100644 --- a/solution/0400-0499/0402.Remove K Digits/README_EN.md +++ b/solution/0400-0499/0402.Remove K Digits/README_EN.md @@ -42,7 +42,7 @@ ## Solutions -**Approach 1: Greedy Algorithm** +**Solution 1: Greedy Algorithm** diff --git a/solution/0400-0499/0403.Frog Jump/README_EN.md b/solution/0400-0499/0403.Frog Jump/README_EN.md index 6105348936ae0..3c79b290f96e9 100644 --- a/solution/0400-0499/0403.Frog Jump/README_EN.md +++ b/solution/0400-0499/0403.Frog Jump/README_EN.md @@ -39,13 +39,13 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** DP, use `dp[i][k]` to indicate whether `i` can be reached when the last jump was `k` units, and define the base case as `dp[0][0] = True` (starting point is at index 0). Because "the frog's last jump was `k` units, its next jump must be either `k - 1`, `k`, or `k + 1` units", so if any of `dp[j][k-1], dp[j][k], dp[j][k + 1]` is true, frog can jump from `j` to `i`. -**Approach 2: Backtracking** +**Solution 2: Backtracking** diff --git a/solution/0400-0499/0454.4Sum II/README_EN.md b/solution/0400-0499/0454.4Sum II/README_EN.md index f2d1bf7465527..2555a9689d021 100644 --- a/solution/0400-0499/0454.4Sum II/README_EN.md +++ b/solution/0400-0499/0454.4Sum II/README_EN.md @@ -44,7 +44,7 @@ The two tuples are: ## Solutions -**Approach 1: HashMap** +**Solution 1: HashMap** Time complexity $O(n^2)$, Space complexity $O(n^2)$. diff --git a/solution/0600-0699/0651.4 Keys Keyboard/README.md b/solution/0600-0699/0651.4 Keys Keyboard/README.md index 0c5654aa096af..0edbcccf22c3a 100644 --- a/solution/0600-0699/0651.4 Keys Keyboard/README.md +++ b/solution/0600-0699/0651.4 Keys Keyboard/README.md @@ -53,14 +53,33 @@ A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V **方法一:动态规划** -定义 $dp[i]$ 表示前 $i$ 个按键可以显示的最大个数。 +我们定义 $f[i][k]$ 表示前 $n+1$ 次按键后,且最后一次为第 $k$ 种按键时,屏幕上最多可以显示的 A 的个数。其中 $k$ 的取值为 $0, 1, 2, 3$,分别表示最后一次按键为 A、Ctrl+A、Ctrl+C、Ctrl+V。初始时 $f[0][0]=1$,表示第一次按键为 A,屏幕上显示一个 A。答案为 $\max(f[n-1][0], f[n-1][3])$。 -我们可以发现,要显示最多的 `A`,要么一直按 `A`,要么以 `Ctrl-V` 结束。 +考虑 $f[i][k]$,其中 $i \in [1, n-1]$: -- 一直按 `A` 的情况,满足 $dp[i] = i$。 -- 以 `Ctrl-V` 结束的情况,我们枚举对应的 `Ctrl-A` 的位置 $j$,可以得到 $dp[i]=max(dp[i], dp[j-1] \times (i - j))$。 +- 当 $k=0$ 时,表示最后一次按键为 A,那么上一次按键可以为 A、Ctrl+V 中的任意一种,因此 $f[i][0]=\max(f[i-1][0], f[i-1][3]) + 1$; +- 当 $k=1$ 时,表示最后一次按键为 Ctrl+A,那么上一次按键可以为 A、Ctrl+V 中的任意一种,因此 $f[i][1]=\max(f[i-1][0], f[i-1][3])$; +- 当 $k=2$ 时,表示最后一次按键为 Ctrl+C,那么上一次按键只能为 Ctrl+A,因此 $f[i][2]=f[i-1][1]$; +- 当 $k=3$ 时,表示最后一次按键为 Ctrl+V,那么我们需要枚举上一次按 Ctrl+C 的位置 $j$,即 $f[i][3]=\max_{0 \leq j \leq i-1} f[j][2] \times (i-k+1)$。 -时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。 +最终答案为 $\max(f[n-1][0], f[n-1][3])$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为按键次数。 + +**方法二:动态规划(优化)** + +我们可以优化方法一中的状态定义。 + +我们定义 $f[i]$ 表示前 $i$ 次按键后,且最后一次按键为 A 或者 Ctrl+V 时,屏幕上最多可以显示的 A 的个数。 + +考虑 $f[i]$,其中 $i \in [1, n]$: + +- 当最后一次按键为 A 时,有 $f[i]=f[i-1]+1$。 +- 当最后一次按键为 Ctrl+V 时,我们需要枚举上一次按 Ctrl+C 的位置 $j$,即 $f[i]=\max_{0 \leq j \leq i-1} f[j] \times (i-j-1)$。 + +最终答案为 $f[n]$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为按键次数。 @@ -71,11 +90,26 @@ A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V ```python class Solution: def maxA(self, n: int) -> int: - dp = list(range(n + 1)) - for i in range(3, n + 1): - for j in range(2, i - 1): - dp[i] = max(dp[i], dp[j - 1] * (i - j)) - return dp[-1] + f = [[0] * 4 for _ in range(n)] + f[0][0] = 1 + for i in range(1, n): + f[i][0] = max(f[i - 1][0], f[i - 1][3]) + 1 + f[i][1] = max(f[i - 1][0], f[i - 1][3]) + f[i][2] = f[i - 1][1] + for j in range(i): + f[i][3] = max(f[i][3], f[j][2] * (i - j + 1)) + return max(f[-1][0], f[-1][3]) +``` + +```python +class Solution: + def maxA(self, n: int) -> int: + f = [0] * (n + 1) + for i in range(1, n + 1): + f[i] = f[i - 1] + 1 + for j in range(2, i): + f[i] = max(f[i], f[j - 2] * (i - j + 1)) + return f[n] ``` ### **Java** @@ -85,16 +119,32 @@ class Solution: ```java class Solution { public int maxA(int n) { - int[] dp = new int[n + 1]; - for (int i = 0; i < n + 1; ++i) { - dp[i] = i; + int[][] f = new int[n][4]; + f[0][0] = 1; + for (int i = 1; i < n; ++i) { + f[i][0] = Math.max(f[i - 1][0], f[i - 1][3]) + 1; + f[i][1] = Math.max(f[i - 1][0], f[i - 1][3]); + f[i][2] = f[i - 1][1]; + for (int j = 0; j < i; ++j) { + f[i][3] = Math.max(f[i][3], f[j][2] * (i - j + 1)); + } } - for (int i = 3; i < n + 1; ++i) { - for (int j = 2; j < i - 1; ++j) { - dp[i] = Math.max(dp[i], dp[j - 1] * (i - j)); + return Math.max(f[n - 1][0], f[n - 1][3]); + } +} +``` + +```java +class Solution { + public int maxA(int n) { + int[] f = new int[n + 1]; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + for (int j = 2; j < i; ++j) { + f[i] = Math.max(f[i], f[j - 2] * (i - j + 1)); } } - return dp[n]; + return f[n]; } } ``` @@ -105,14 +155,35 @@ class Solution { class Solution { public: int maxA(int n) { - vector dp(n + 1); - iota(dp.begin(), dp.end(), 0); - for (int i = 3; i < n + 1; ++i) { - for (int j = 2; j < i - 1; ++j) { - dp[i] = max(dp[i], dp[j - 1] * (i - j)); + int f[n][4]; + memset(f, 0, sizeof(f)); + f[0][0] = 1; + for (int i = 1; i < n; ++i) { + f[i][0] = max(f[i - 1][0], f[i - 1][3]) + 1; + f[i][1] = max(f[i - 1][0], f[i - 1][3]); + f[i][2] = f[i - 1][1]; + for (int j = 0; j < i; ++j) { + f[i][3] = max(f[i][3], f[j][2] * (i - j + 1)); + } + } + return max(f[n - 1][0], f[n - 1][3]); + } +}; +``` + +```cpp +class Solution { +public: + int maxA(int n) { + int f[n + 1]; + memset(f, 0, sizeof(f)); + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + for (int j = 2; j < i; ++j) { + f[i] = max(f[i], f[j - 2] * (i - j + 1)); } } - return dp[n]; + return f[n]; } }; ``` @@ -121,16 +192,37 @@ public: ```go func maxA(n int) int { - dp := make([]int, n+1) - for i := range dp { - dp[i] = i + f := make([][4]int, n) + f[0][0] = 1 + for i := 1; i < n; i++ { + f[i][0] = max(f[i-1][0], f[i-1][3]) + 1 + f[i][1] = max(f[i-1][0], f[i-1][3]) + f[i][2] = f[i-1][1] + for j := 0; j < i; j++ { + f[i][3] = max(f[i][3], f[j][2]*(i-j+1)) + } + } + return max(max(f[n-1][0], f[n-1][1]), max(f[n-1][2], f[n-1][3])) +} + +func max(a, b int) int { + if a > b { + return a } - for i := 3; i < n+1; i++ { - for j := 2; j < i-1; j++ { - dp[i] = max(dp[i], dp[j-1]*(i-j)) + return b +} +``` + +```go +func maxA(n int) int { + f := make([]int, n+1) + for i := 1; i <= n; i++ { + f[i] = f[i-1] + 1 + for j := 2; j < i; j++ { + f[i] = max(f[i], f[j-2]*(i-j+1)) } } - return dp[n] + return f[n] } func max(a, b int) int { diff --git a/solution/0600-0699/0651.4 Keys Keyboard/README_EN.md b/solution/0600-0699/0651.4 Keys Keyboard/README_EN.md index d79a478d0bfb3..dc8444d3752e9 100644 --- a/solution/0600-0699/0651.4 Keys Keyboard/README_EN.md +++ b/solution/0600-0699/0651.4 Keys Keyboard/README_EN.md @@ -50,11 +50,26 @@ A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V ```python class Solution: def maxA(self, n: int) -> int: - dp = list(range(n + 1)) - for i in range(3, n + 1): - for j in range(2, i - 1): - dp[i] = max(dp[i], dp[j - 1] * (i - j)) - return dp[-1] + f = [[0] * 4 for _ in range(n)] + f[0][0] = 1 + for i in range(1, n): + f[i][0] = max(f[i - 1][0], f[i - 1][3]) + 1 + f[i][1] = max(f[i - 1][0], f[i - 1][3]) + f[i][2] = f[i - 1][1] + for j in range(i): + f[i][3] = max(f[i][3], f[j][2] * (i - j + 1)) + return max(f[-1][0], f[-1][3]) +``` + +```python +class Solution: + def maxA(self, n: int) -> int: + f = [0] * (n + 1) + for i in range(1, n + 1): + f[i] = f[i - 1] + 1 + for j in range(2, i): + f[i] = max(f[i], f[j - 2] * (i - j + 1)) + return f[n] ``` ### **Java** @@ -62,16 +77,32 @@ class Solution: ```java class Solution { public int maxA(int n) { - int[] dp = new int[n + 1]; - for (int i = 0; i < n + 1; ++i) { - dp[i] = i; + int[][] f = new int[n][4]; + f[0][0] = 1; + for (int i = 1; i < n; ++i) { + f[i][0] = Math.max(f[i - 1][0], f[i - 1][3]) + 1; + f[i][1] = Math.max(f[i - 1][0], f[i - 1][3]); + f[i][2] = f[i - 1][1]; + for (int j = 0; j < i; ++j) { + f[i][3] = Math.max(f[i][3], f[j][2] * (i - j + 1)); + } } - for (int i = 3; i < n + 1; ++i) { - for (int j = 2; j < i - 1; ++j) { - dp[i] = Math.max(dp[i], dp[j - 1] * (i - j)); + return Math.max(f[n - 1][0], f[n - 1][3]); + } +} +``` + +```java +class Solution { + public int maxA(int n) { + int[] f = new int[n + 1]; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + for (int j = 2; j < i; ++j) { + f[i] = Math.max(f[i], f[j - 2] * (i - j + 1)); } } - return dp[n]; + return f[n]; } } ``` @@ -82,14 +113,35 @@ class Solution { class Solution { public: int maxA(int n) { - vector dp(n + 1); - iota(dp.begin(), dp.end(), 0); - for (int i = 3; i < n + 1; ++i) { - for (int j = 2; j < i - 1; ++j) { - dp[i] = max(dp[i], dp[j - 1] * (i - j)); + int f[n][4]; + memset(f, 0, sizeof(f)); + f[0][0] = 1; + for (int i = 1; i < n; ++i) { + f[i][0] = max(f[i - 1][0], f[i - 1][3]) + 1; + f[i][1] = max(f[i - 1][0], f[i - 1][3]); + f[i][2] = f[i - 1][1]; + for (int j = 0; j < i; ++j) { + f[i][3] = max(f[i][3], f[j][2] * (i - j + 1)); + } + } + return max(f[n - 1][0], f[n - 1][3]); + } +}; +``` + +```cpp +class Solution { +public: + int maxA(int n) { + int f[n + 1]; + memset(f, 0, sizeof(f)); + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + for (int j = 2; j < i; ++j) { + f[i] = max(f[i], f[j - 2] * (i - j + 1)); } } - return dp[n]; + return f[n]; } }; ``` @@ -98,16 +150,37 @@ public: ```go func maxA(n int) int { - dp := make([]int, n+1) - for i := range dp { - dp[i] = i + f := make([][4]int, n) + f[0][0] = 1 + for i := 1; i < n; i++ { + f[i][0] = max(f[i-1][0], f[i-1][3]) + 1 + f[i][1] = max(f[i-1][0], f[i-1][3]) + f[i][2] = f[i-1][1] + for j := 0; j < i; j++ { + f[i][3] = max(f[i][3], f[j][2]*(i-j+1)) + } + } + return max(max(f[n-1][0], f[n-1][1]), max(f[n-1][2], f[n-1][3])) +} + +func max(a, b int) int { + if a > b { + return a } - for i := 3; i < n+1; i++ { - for j := 2; j < i-1; j++ { - dp[i] = max(dp[i], dp[j-1]*(i-j)) + return b +} +``` + +```go +func maxA(n int) int { + f := make([]int, n+1) + for i := 1; i <= n; i++ { + f[i] = f[i-1] + 1 + for j := 2; j < i; j++ { + f[i] = max(f[i], f[j-2]*(i-j+1)) } } - return dp[n] + return f[n] } func max(a, b int) int { diff --git a/solution/0600-0699/0651.4 Keys Keyboard/Solution.java b/solution/0600-0699/0651.4 Keys Keyboard/Solution.java index 242b7e20463eb..cae20dca9ffd5 100644 --- a/solution/0600-0699/0651.4 Keys Keyboard/Solution.java +++ b/solution/0600-0699/0651.4 Keys Keyboard/Solution.java @@ -1,14 +1,12 @@ class Solution { public int maxA(int n) { - int[] dp = new int[n + 1]; - for (int i = 0; i < n + 1; ++i) { - dp[i] = i; - } - for (int i = 3; i < n + 1; ++i) { - for (int j = 2; j < i - 1; ++j) { - dp[i] = Math.max(dp[i], dp[j - 1] * (i - j)); + int[] f = new int[n + 1]; + for (int i = 1; i <= n; ++i) { + f[i] = f[i - 1] + 1; + for (int j = 2; j < i; ++j) { + f[i] = Math.max(f[i], f[j - 2] * (i - j + 1)); } } - return dp[n]; + return f[n]; } } \ No newline at end of file diff --git a/solution/0600-0699/0651.4 Keys Keyboard/Solution.py b/solution/0600-0699/0651.4 Keys Keyboard/Solution.py index 04270b0bb2138..df906d5eacb17 100644 --- a/solution/0600-0699/0651.4 Keys Keyboard/Solution.py +++ b/solution/0600-0699/0651.4 Keys Keyboard/Solution.py @@ -1,7 +1,8 @@ class Solution: def maxA(self, n: int) -> int: - dp = list(range(n + 1)) - for i in range(3, n + 1): - for j in range(2, i - 1): - dp[i] = max(dp[i], dp[j - 1] * (i - j)) - return dp[-1] + f = [0] * (n + 1) + for i in range(1, n + 1): + f[i] = f[i - 1] + 1 + for j in range(2, i): + f[i] = max(f[i], f[j - 2] * (i - j + 1)) + return f[n] diff --git a/solution/0600-0699/0678.Valid Parenthesis String/README_EN.md b/solution/0600-0699/0678.Valid Parenthesis String/README_EN.md index 8e67cc037e9c3..1730a1e7c23a6 100644 --- a/solution/0600-0699/0678.Valid Parenthesis String/README_EN.md +++ b/solution/0600-0699/0678.Valid Parenthesis String/README_EN.md @@ -36,7 +36,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** Let `dp[i][j]` be true if and only if the interval `s[i], s[i+1], ..., s[j]` can be made valid. Then `dp[i][j]` is true only if: @@ -46,7 +46,7 @@ Let `dp[i][j]` be true if and only if the interval `s[i], s[i+1], ..., s[j]` can - Time Complexity: $O(n^3)$, where $n$ is the length of the string. There are $O(n^2)$ states corresponding to entries of dp, and we do an average of $O(n)$ work on each state. - Space Complexity: $O(n^2)$. -**Approach 2: Greedy** +**Solution 2: Greedy** Scan twice, first from left to right to make sure that each of the closing brackets is matched successfully, and second from right to left to make sure that each of the opening brackets is matched successfully. diff --git a/solution/1000-1099/1023.Camelcase Matching/README_EN.md b/solution/1000-1099/1023.Camelcase Matching/README_EN.md index d6f984495ec59..0e0fa17570556 100644 --- a/solution/1000-1099/1023.Camelcase Matching/README_EN.md +++ b/solution/1000-1099/1023.Camelcase Matching/README_EN.md @@ -47,7 +47,7 @@ ## Solutions -**Approach 1: Two Pointers** +**Solution 1: Two Pointers** We can traverse every string in `queries` and check whether it matches `pattern` or not. If it matches, we add `true` to the answer array, otherwise we add `false`. diff --git a/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README.md b/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README.md index 84702da10b6f6..3d666e83906c6 100644 --- a/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README.md +++ b/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README.md @@ -55,17 +55,19 @@ **方法一:前缀和 + 枚举** -我们先预处理得到数组 `nums` 的前缀和数组 $s$,其中 $s[i]$ 表示 $nums$ 中前 $i$ 个元素的和。 +我们先预处理得到数组 $nums$ 的前缀和数组 $s$,其中 $s[i]$ 表示 $nums$ 中前 $i$ 个元素的和。 接下来,我们分两种情况枚举: -假设 $firstLen$ 个元素的子数组在 $secondLen$ 个元素的子数组的左边,那么我们可以枚举 $secondLen$ 个元素的子数组的左端点 $i$,用变量 $t$ 维护左边 $firstLen$ 个元素的子数组的最大和,那么答案就是 $t + s[i + secondLen] - s[i]$。枚举完所有的 $i$,就可以得到候选答案。 +假设 $firstLen$ 个元素的子数组在 $secondLen$ 个元素的子数组的左边,那么我们可以枚举 $secondLen$ 个元素的子数组的左端点 $i$,用变量 $t$ 维护左边 $firstLen$ 个元素的子数组的最大和,那么当前最大和就是 $t + s[i + secondLen] - s[i]$。其中 $s[i + secondLen] - s[i]$ 表示 $secondLen$ 个元素的子数组的和。枚举完所有的 $i$,就得到了第一种情况下的最大和。 -假设 $secondLen$ 个元素的子数组在 $firstLen$ 个元素的子数组的左边,那么我们可以枚举 $firstLen$ 个元素的子数组的左端点 $i$,用变量 $t$ 维护左边 $secondLen$ 个元素的子数组的最大和,那么答案就是 $t + s[i + firstLen] - s[i]$。枚举完所有的 $i$,就可以得到候选答案。 +假设 $secondLen$ 个元素的子数组在 $firstLen$ 个元素的子数组的左边,那么我们可以枚举 $firstLen$ 个元素的子数组的左端点 $i$,用变量 $t$ 维护左边 $secondLen$ 个元素的子数组的最大和,那么当前最大和就是 $t + s[i + firstLen] - s[i]$。其中 $s[i + firstLen] - s[i]$ 表示 $firstLen$ 个元素的子数组的和。枚举完所有的 $i$,就得到了第二种情况下的最大和。 -最后,我们取两种情况下的候选答案的最大值即可。 +取两种情况下的最大值作为答案即可。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。 +我们也可以将上面两个情况抽取成一个函数 $f(a, b)$,那么答案就是 $\max(f(firstLen, secondLen), f(secondLen, firstLen))$。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。 @@ -93,6 +95,23 @@ class Solution: return ans ``` +```python +class Solution: + def maxSumTwoNoOverlap(self, nums: List[int], firstLen: int, secondLen: int) -> int: + def f(a: int, b: int) -> int: + ans = t = 0 + i = a + while i + b - 1 < n: + t = max(t, s[i] - s[i - a]) + ans = max(ans, t + s[i + b] - s[i]) + i += 1 + return ans + + n = len(nums) + s = list(accumulate(nums, initial=0)) + return max(f(firstLen, secondLen), f(secondLen, firstLen)) +``` + ### **Java** @@ -119,6 +138,31 @@ class Solution { } ``` +```java +class Solution { + private int[] s; + private int n; + + public int maxSumTwoNoOverlap(int[] nums, int firstLen, int secondLen) { + n = nums.length; + s = new int[n + 1]; + for (int i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + return Math.max(f(firstLen, secondLen), f(secondLen, firstLen)); + } + + private int f(int a, int b) { + int ans = 0; + for (int i = a, t = 0; i + b - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - a]); + ans = Math.max(ans, t + s[i + b] - s[i]); + } + return ans; + } +} +``` + ### **C++** ```cpp @@ -144,6 +188,28 @@ public: }; ``` +```cpp +class Solution { +public: + int maxSumTwoNoOverlap(vector& nums, int firstLen, int secondLen) { + int n = nums.size(); + vector s(n + 1); + for (int i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + auto f = [&](int a, int b) -> int { + int ans = 0; + for (int i = a, t = 0; i + b - 1 < n; ++i) { + t = max(t, s[i] - s[i - a]); + ans = max(ans, t + s[i + b] - s[i]); + } + return ans; + }; + return max(f(firstLen, secondLen), f(secondLen, firstLen)); + } +}; +``` + ### **Go** ```go @@ -172,6 +238,80 @@ func max(a, b int) int { } ``` +```go +func maxSumTwoNoOverlap(nums []int, firstLen int, secondLen int) (ans int) { + n := len(nums) + s := make([]int, n+1) + for i, x := range nums { + s[i+1] = s[i] + x + } + f := func(a, b int) (ans int) { + for i, t := a, 0; i+b-1 < n; i++ { + t = max(t, s[i]-s[i-a]) + ans = max(ans, t+s[i+b]-s[i]) + } + return + } + return max(f(firstLen, secondLen), f(secondLen, firstLen)) +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function maxSumTwoNoOverlap( + nums: number[], + firstLen: number, + secondLen: number, +): number { + const n = nums.length; + const s: number[] = new Array(n + 1).fill(0); + for (let i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + let ans = 0; + for (let i = firstLen, t = 0; i + secondLen - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - firstLen]); + ans = Math.max(ans, t + s[i + secondLen] - s[i]); + } + for (let i = secondLen, t = 0; i + firstLen - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - secondLen]); + ans = Math.max(ans, t + s[i + firstLen] - s[i]); + } + return ans; +} +``` + +```ts +function maxSumTwoNoOverlap( + nums: number[], + firstLen: number, + secondLen: number, +): number { + const n = nums.length; + const s: number[] = new Array(n + 1).fill(0); + for (let i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + const f = (a: number, b: number): number => { + let ans = 0; + for (let i = a, t = 0; i + b - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - a]); + ans = Math.max(ans, t + s[i + b] - s[i]); + } + return ans; + }; + return Math.max(f(firstLen, secondLen), f(secondLen, firstLen)); +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README_EN.md b/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README_EN.md index ad19b9e4060e6..3c29cd96a2ae4 100644 --- a/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README_EN.md +++ b/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/README_EN.md @@ -47,6 +47,20 @@ ## Solutions +**Solution 1: Prefix Sum + Enumeration** + +First, we preprocess the prefix sum array $s$ of the array `nums`, where $s[i]$ indicates the sum of the first $i$ elements in `nums`. + +Then, we enumerate in two cases: + +Suppose $firstLen$ elements of the subarray are on the left side of the $secondLen$ elements of the subarray, then we can enumerate the left endpoint $i$ of the $secondLen$ elements of the subarray, use the variable $t$ to maintain the maximum sum of the left $firstLen$ elements of the subarray, then the current maximum sum is $t + s[i + secondLen] - s[i]$. Where $s[i + secondLen] - s[i]$ represents the sum of the $secondLen$ elements of the subarray. After enumerating all $i$, we get the maximum sum of the first case. + +Suppose the $secondLen$ elements of the subarray are on the left side of the $firstLen$ elements of the subarray, then we can enumerate the left endpoint $i$ of the $firstLen$ elements of the subarray, use the variable $t$ to maintain the maximum sum of the left $secondLen$ elements of the subarray, then the current maximum sum is $t + s[i + firstLen] - s[i]$. Where $s[i + firstLen] - s[i]$ represents the sum of the $firstLen$ elements of the subarray. After enumerating all $i$, we get the maximum sum of the second case. + +Take the maximum value of the two cases as the answer. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Where $n$ is the length of the array `nums`. + ### **Python3** @@ -71,6 +85,23 @@ class Solution: return ans ``` +```python +class Solution: + def maxSumTwoNoOverlap(self, nums: List[int], firstLen: int, secondLen: int) -> int: + def f(a: int, b: int) -> int: + ans = t = 0 + i = a + while i + b - 1 < n: + t = max(t, s[i] - s[i - a]) + ans = max(ans, t + s[i + b] - s[i]) + i += 1 + return ans + + n = len(nums) + s = list(accumulate(nums, initial=0)) + return max(f(firstLen, secondLen), f(secondLen, firstLen)) +``` + ### **Java** ```java @@ -95,6 +126,31 @@ class Solution { } ``` +```java +class Solution { + private int[] s; + private int n; + + public int maxSumTwoNoOverlap(int[] nums, int firstLen, int secondLen) { + n = nums.length; + s = new int[n + 1]; + for (int i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + return Math.max(f(firstLen, secondLen), f(secondLen, firstLen)); + } + + private int f(int a, int b) { + int ans = 0; + for (int i = a, t = 0; i + b - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - a]); + ans = Math.max(ans, t + s[i + b] - s[i]); + } + return ans; + } +} +``` + ### **C++** ```cpp @@ -120,6 +176,28 @@ public: }; ``` +```cpp +class Solution { +public: + int maxSumTwoNoOverlap(vector& nums, int firstLen, int secondLen) { + int n = nums.size(); + vector s(n + 1); + for (int i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + auto f = [&](int a, int b) -> int { + int ans = 0; + for (int i = a, t = 0; i + b - 1 < n; ++i) { + t = max(t, s[i] - s[i - a]); + ans = max(ans, t + s[i + b] - s[i]); + } + return ans; + }; + return max(f(firstLen, secondLen), f(secondLen, firstLen)); + } +}; +``` + ### **Go** ```go @@ -148,6 +226,80 @@ func max(a, b int) int { } ``` +```go +func maxSumTwoNoOverlap(nums []int, firstLen int, secondLen int) (ans int) { + n := len(nums) + s := make([]int, n+1) + for i, x := range nums { + s[i+1] = s[i] + x + } + f := func(a, b int) (ans int) { + for i, t := a, 0; i+b-1 < n; i++ { + t = max(t, s[i]-s[i-a]) + ans = max(ans, t+s[i+b]-s[i]) + } + return + } + return max(f(firstLen, secondLen), f(secondLen, firstLen)) +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +### **TypeScript** + +```ts +function maxSumTwoNoOverlap( + nums: number[], + firstLen: number, + secondLen: number, +): number { + const n = nums.length; + const s: number[] = new Array(n + 1).fill(0); + for (let i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + let ans = 0; + for (let i = firstLen, t = 0; i + secondLen - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - firstLen]); + ans = Math.max(ans, t + s[i + secondLen] - s[i]); + } + for (let i = secondLen, t = 0; i + firstLen - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - secondLen]); + ans = Math.max(ans, t + s[i + firstLen] - s[i]); + } + return ans; +} +``` + +```ts +function maxSumTwoNoOverlap( + nums: number[], + firstLen: number, + secondLen: number, +): number { + const n = nums.length; + const s: number[] = new Array(n + 1).fill(0); + for (let i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + const f = (a: number, b: number): number => { + let ans = 0; + for (let i = a, t = 0; i + b - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - a]); + ans = Math.max(ans, t + s[i + b] - s[i]); + } + return ans; + }; + return Math.max(f(firstLen, secondLen), f(secondLen, firstLen)); +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/Solution.ts b/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/Solution.ts new file mode 100644 index 0000000000000..a73138d0b3233 --- /dev/null +++ b/solution/1000-1099/1031.Maximum Sum of Two Non-Overlapping Subarrays/Solution.ts @@ -0,0 +1,21 @@ +function maxSumTwoNoOverlap( + nums: number[], + firstLen: number, + secondLen: number, +): number { + const n = nums.length; + const s: number[] = new Array(n + 1).fill(0); + for (let i = 0; i < n; ++i) { + s[i + 1] = s[i] + nums[i]; + } + let ans = 0; + for (let i = firstLen, t = 0; i + secondLen - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - firstLen]); + ans = Math.max(ans, t + s[i + secondLen] - s[i]); + } + for (let i = secondLen, t = 0; i + firstLen - 1 < n; ++i) { + t = Math.max(t, s[i] - s[i - secondLen]); + ans = Math.max(ans, t + s[i + firstLen] - s[i]); + } + return ans; +} diff --git a/solution/1000-1099/1043.Partition Array for Maximum Sum/README_EN.md b/solution/1000-1099/1043.Partition Array for Maximum Sum/README_EN.md index 52b1d01626c66..4a8c82b3162c1 100644 --- a/solution/1000-1099/1043.Partition Array for Maximum Sum/README_EN.md +++ b/solution/1000-1099/1043.Partition Array for Maximum Sum/README_EN.md @@ -42,7 +42,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** We define $f[i]$ to represent the maximum element sum of the first $i$ elements of the array after separating them into several subarrays. At the beginning, $f[i]=0$, and the answer is $f[n]$. diff --git a/solution/1000-1099/1048.Longest String Chain/README.md b/solution/1000-1099/1048.Longest String Chain/README.md index a270912a311bc..25b45aa117698 100644 --- a/solution/1000-1099/1048.Longest String Chain/README.md +++ b/solution/1000-1099/1048.Longest String Chain/README.md @@ -58,7 +58,17 @@ -先按字符串长度升序排列,再利用动态规划或者哈希表求解。 +**方法一:排序 + 哈希表** + +根据题目描述,字符串链中的单词必须按照长度递增的顺序排列。因此,我们首先对数组 `words` 中的字符串按照长度进行升序排序。在排好序的数组中,如果字符串 $a$ 是字符串 $b$ 的前身,那么字符串 $a$ 的长度一定是字符串 $b$ 的长度减去 $1$。 + +我们可以使用哈希表 $d$ 存储排好序的数组中的每个字符串的最长字符串链长度。 + +接下来,遍历数组 `words` 中的每个字符串 $s$,计算出它的所有前身字符串 $t$,每一个前身字符串 $t$ 是将字符串 $s$ 中的一个字符删除后得到的。如果哈希表中存在字符串 $t$,那么我们就能够用 $d[t] + 1$ 更新 $d[s]$,即 $d[s] = \max(d[s], d[t] + 1)$。然后我们更新答案为所有 $d[s]$ 中的最大值。 + +遍历结束后,返回答案即可。 + +时间复杂度 $(n \times (\log n + m^2))$,空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别是单词数组 `words` 的长度和单词的最大长度。本题中 $n \leq 1000$, $m \leq 16$。 @@ -66,143 +76,220 @@ -动态规划: - ```python class Solution: def longestStrChain(self, words: List[str]) -> int: - def check(w1, w2): - if len(w2) - len(w1) != 1: - return False - i = j = cnt = 0 - while i < len(w1) and j < len(w2): - if w1[i] != w2[j]: - cnt += 1 - else: + def check(s: str, t: str) -> bool: + m, n = len(s), len(t) + i = j = 0 + while i < m and j < n: + if s[i] == t[j]: i += 1 j += 1 - return cnt < 2 and i == len(w1) - - n = len(words) - dp = [1] * (n + 1) - words.sort(key=lambda x: len(x)) - res = 1 - for i in range(1, n): - for j in range(i): - if check(words[j], words[i]): - dp[i] = max(dp[i], dp[j] + 1) - res = max(res, dp[i]) - return res + return i == m + + words.sort(key=len) + f = [1] * len(words) + d = defaultdict(list) + for i, w in enumerate(words): + for j in d[len(w) - 1]: + if check(words[j], w): + f[i] = max(f[i], f[j] + 1) + d[len(w)].append(i) + return max(f) ``` -哈希表: - ```python class Solution: def longestStrChain(self, words: List[str]) -> int: - words.sort(key= lambda x: len(x)) - res = 0 - mp = {} - for word in words: + words.sort(key=len) + d = defaultdict(int) + ans = 0 + for s in words: x = 1 - for i in range(len(word)): - pre = word[:i] + word[i + 1:] - x = max(x, mp.get(pre, 0) + 1) - mp[word] = x - res = max(res, x) - return res + for i in range(len(s)): + t = s[:i] + s[i + 1:] + x = max(x, d[t] + 1) + d[s] = x + ans = max(ans, x) + return ans ``` ### **Java** -哈希表: - ```java class Solution { public int longestStrChain(String[] words) { Arrays.sort(words, Comparator.comparingInt(String::length)); - int res = 0; - Map map = new HashMap<>(); - for (String word : words) { - int x = 1; - for (int i = 0; i < word.length(); ++i) { - String pre = word.substring(0, i) + word.substring(i + 1); - x = Math.max(x, map.getOrDefault(pre, 0) + 1); + int n = words.length; + int[] f = new int[n]; + Arrays.fill(f, 1); + List[] g = new List[17]; + Arrays.setAll(g, k -> new ArrayList<>()); + int ans = 1; + for (int i = 0; i < n; ++i) { + String w = words[i]; + for (int j : g[w.length() - 1]) { + if (check(words[j], w)) { + f[i] = Math.max(f[i], f[j] + 1); + ans = Math.max(ans, f[i]); + } } - map.put(word, x); - res = Math.max(res, x); + g[w.length()].add(i); } - return res; + return ans; + } + + private boolean check(String s, String t) { + int m = s.length(), n = t.length(); + int i = 0, j = 0; + while (i < m && j < n) { + if (s.charAt(i) == t.charAt(j)) { + ++i; + } + ++j; + } + return i == m; } } ``` -### **TypeScript** - -```ts -function longestStrChain(words: string[]): number { - words.sort((a, b) => a.length - b.length); - let ans = 0; - let hashTable = new Map(); - for (let word of words) { - let c = 1; - for (let i = 0; i < word.length; i++) { - let pre = word.substring(0, i) + word.substring(i + 1); - c = Math.max(c, (hashTable.get(pre) || 0) + 1); +```java +class Solution { + public int longestStrChain(String[] words) { + Arrays.sort(words, Comparator.comparingInt(String::length)); + Map d = new HashMap<>(); + int ans = 0; + for (String s : words) { + int x = 0; + for (int i = 0; i < s.length(); ++i) { + String t = s.substring(0, i) + s.substring(i + 1); + x = Math.max(x, d.getOrDefault(t, 0) + 1); + } + d.put(s, x); + ans = Math.max(ans, x); } - hashTable.set(word, c); - ans = Math.max(ans, c); + return ans; } - return ans; } ``` ### **C++** -哈希表: +```cpp +class Solution { +public: + int longestStrChain(vector& words) { + sort(words.begin(), words.end(), [](auto& a, auto& b) { return a.size() < b.size(); }); + int n = words.size(); + int f[n]; + vector g[17]; + int ans = 1; + auto check = [](string& s, string& t) -> bool { + int m = s.size(), n = t.size(); + int i = 0, j = 0; + while (i < m && j < n) { + if (s[i] == t[j]) { + ++i; + } + ++j; + } + return i == m; + }; + for (int i = 0; i < n; ++i) { + f[i] = 1; + auto w = words[i]; + for (int j : g[w.size() - 1]) { + if (check(words[j], w)) { + f[i] = max(f[i], f[j] + 1); + ans = max(ans, f[i]); + } + } + g[w.size()].push_back(i); + } + return ans; + } +}; +``` ```cpp class Solution { public: int longestStrChain(vector& words) { - sort(words.begin(), words.end(), [&](string a, string b) { return a.size() < b.size(); }); - int res = 0; - unordered_map map; - for (auto word : words) { + sort(words.begin(), words.end(), [](auto& a, auto& b) { return a.size() < b.size(); }); + int ans = 0; + unordered_map d; + for (auto& s : words) { int x = 1; - for (int i = 0; i < word.size(); ++i) { - string pre = word.substr(0, i) + word.substr(i + 1); - x = max(x, map[pre] + 1); + for (int i = 0; i < s.size(); ++i) { + string t = s.substr(0, i) + s.substr(i + 1); + x = max(x, d[t] + 1); } - map[word] = x; - res = max(res, x); + d[s] = x; + ans = max(ans, x); } - return res; + return ans; } }; ``` ### **Go** -哈希表: - ```go func longestStrChain(words []string) int { sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) - res := 0 - mp := make(map[string]int) - for _, word := range words { + n := len(words) + f := make([]int, n) + g := [17][]int{} + ans := 1 + check := func(s, t string) bool { + m, n := len(s), len(t) + i, j := 0, 0 + for i < m && j < n { + if s[i] == t[j] { + i++ + } + j++ + } + return i == m + } + for i, w := range words { + f[i] = 1 + for _, j := range g[len(w)-1] { + if check(words[j], w) { + f[i] = max(f[i], f[j]+1) + ans = max(ans, f[i]) + } + } + g[len(w)] = append(g[len(w)], i) + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +```go +func longestStrChain(words []string) (ans int) { + sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) + d := map[string]int{} + for _, s := range words { x := 1 - for i := 0; i < len(word); i++ { - pre := word[0:i] + word[i+1:len(word)] - x = max(x, mp[pre]+1) + for i := 0; i < len(s); i++ { + t := s[:i] + s[i+1:] + x = max(x, d[t]+1) } - mp[word] = x - res = max(res, x) + d[s] = x + ans = max(ans, x) } - return res + return } func max(a, b int) int { @@ -213,6 +300,60 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function longestStrChain(words: string[]): number { + words.sort((a, b) => a.length - b.length); + let ans = 1; + const n = words.length; + const f: number[] = new Array(n).fill(1); + const g: number[][] = new Array(17).fill(0).map(() => []); + const check = (s: string, t: string): boolean => { + const m = s.length; + const n = t.length; + let i = 0; + let j = 0; + while (i < m && j < n) { + if (s[i] === t[j]) { + ++i; + } + ++j; + } + return i === m; + }; + for (let i = 0; i < n; ++i) { + const w = words[i]; + for (const j of g[w.length - 1]) { + if (check(words[j], w)) { + f[i] = Math.max(f[i], f[j] + 1); + ans = Math.max(ans, f[i]); + } + } + g[w.length].push(i); + } + return ans; +} +``` + +```ts +function longestStrChain(words: string[]): number { + words.sort((a, b) => a.length - b.length); + let ans = 0; + const d: Map = new Map(); + for (const s of words) { + let x = 1; + for (let i = 0; i < s.length; ++i) { + const t = s.slice(0, i) + s.slice(i + 1); + x = Math.max(x, (d.get(t) || 0) + 1); + } + d.set(s, x); + ans = Math.max(ans, x); + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1048.Longest String Chain/README_EN.md b/solution/1000-1099/1048.Longest String Chain/README_EN.md index c54150c022ee3..54daca642b80b 100644 --- a/solution/1000-1099/1048.Longest String Chain/README_EN.md +++ b/solution/1000-1099/1048.Longest String Chain/README_EN.md @@ -53,6 +53,18 @@ ## Solutions +**Solution 1: Sorting + Hash Table** + +According to the description of the problem, the words in the string chain must be sorted in order of increasing length. Therefore, we first sort the strings in the array `words` in ascending order by length. In the sorted array, if string $a$ is the predecessor of string $b$, then the length of string $a$ must be the length of string $b$ minus $1$. + +We can use the hash table $d$ to store the longest string chain length of each string in the sorted array. + +Next, traverse each string $s$ in the array `words` and calculate all predecessor strings $t$. Each predecessor string $t$ is obtained by deleting one character from string $s$. If string $t$ exists in the hash table, then we can update $d[s]$ with $d[t] + 1$, that is, $d[s] = \max(d[s], d[t] + 1)$. Then we update the answer to the maximum value of all $d[s]$. + +After the traversal is over, return the answer. + +The time complexity is $(n \times (\log n + m^2))$, and the space complexity is $O(n)$. Where $n$ and $m$ are the length of the word array `words` and the maximum length of the word respectively. In this question, $n \leq 1000$, $m \leq 16$. + ### **Python3** @@ -60,44 +72,40 @@ ```python class Solution: def longestStrChain(self, words: List[str]) -> int: - def check(w1, w2): - if len(w2) - len(w1) != 1: - return False - i = j = cnt = 0 - while i < len(w1) and j < len(w2): - if w1[i] != w2[j]: - cnt += 1 - else: + def check(s: str, t: str) -> bool: + m, n = len(s), len(t) + i = j = 0 + while i < m and j < n: + if s[i] == t[j]: i += 1 j += 1 - return cnt < 2 and i == len(w1) - - n = len(words) - dp = [1] * (n + 1) - words.sort(key=lambda x: len(x)) - res = 1 - for i in range(1, n): - for j in range(i): - if check(words[j], words[i]): - dp[i] = max(dp[i], dp[j] + 1) - res = max(res, dp[i]) - return res + return i == m + + words.sort(key=len) + f = [1] * len(words) + d = defaultdict(list) + for i, w in enumerate(words): + for j in d[len(w) - 1]: + if check(words[j], w): + f[i] = max(f[i], f[j] + 1) + d[len(w)].append(i) + return max(f) ``` ```python class Solution: def longestStrChain(self, words: List[str]) -> int: - words.sort(key= lambda x: len(x)) - res = 0 - mp = {} - for word in words: + words.sort(key=len) + d = defaultdict(int) + ans = 0 + for s in words: x = 1 - for i in range(len(word)): - pre = word[:i] + word[i + 1:] - x = max(x, mp.get(pre, 0) + 1) - mp[word] = x - res = max(res, x) - return res + for i in range(len(s)): + t = s[:i] + s[i + 1:] + x = max(x, d[t] + 1) + d[s] = x + ans = max(ans, x) + return ans ``` ### **Java** @@ -106,39 +114,56 @@ class Solution: class Solution { public int longestStrChain(String[] words) { Arrays.sort(words, Comparator.comparingInt(String::length)); - int res = 0; - Map map = new HashMap<>(); - for (String word : words) { - int x = 1; - for (int i = 0; i < word.length(); ++i) { - String pre = word.substring(0, i) + word.substring(i + 1); - x = Math.max(x, map.getOrDefault(pre, 0) + 1); + int n = words.length; + int[] f = new int[n]; + Arrays.fill(f, 1); + List[] g = new List[17]; + Arrays.setAll(g, k -> new ArrayList<>()); + int ans = 1; + for (int i = 0; i < n; ++i) { + String w = words[i]; + for (int j : g[w.length() - 1]) { + if (check(words[j], w)) { + f[i] = Math.max(f[i], f[j] + 1); + ans = Math.max(ans, f[i]); + } } - map.put(word, x); - res = Math.max(res, x); + g[w.length()].add(i); } - return res; + return ans; + } + + private boolean check(String s, String t) { + int m = s.length(), n = t.length(); + int i = 0, j = 0; + while (i < m && j < n) { + if (s.charAt(i) == t.charAt(j)) { + ++i; + } + ++j; + } + return i == m; } } ``` -### **TypeScript** - -```ts -function longestStrChain(words: string[]): number { - words.sort((a, b) => a.length - b.length); - let ans = 0; - let hashTable = new Map(); - for (let word of words) { - let c = 1; - for (let i = 0; i < word.length; i++) { - let pre = word.substring(0, i) + word.substring(i + 1); - c = Math.max(c, (hashTable.get(pre) || 0) + 1); +```java +class Solution { + public int longestStrChain(String[] words) { + Arrays.sort(words, Comparator.comparingInt(String::length)); + Map d = new HashMap<>(); + int ans = 0; + for (String s : words) { + int x = 0; + for (int i = 0; i < s.length(); ++i) { + String t = s.substring(0, i) + s.substring(i + 1); + x = Math.max(x, d.getOrDefault(t, 0) + 1); + } + d.put(s, x); + ans = Math.max(ans, x); } - hashTable.set(word, c); - ans = Math.max(ans, c); + return ans; } - return ans; } ``` @@ -148,19 +173,55 @@ function longestStrChain(words: string[]): number { class Solution { public: int longestStrChain(vector& words) { - sort(words.begin(), words.end(), [&](string a, string b) { return a.size() < b.size(); }); - int res = 0; - unordered_map map; - for (auto word : words) { + sort(words.begin(), words.end(), [](auto& a, auto& b) { return a.size() < b.size(); }); + int n = words.size(); + int f[n]; + vector g[17]; + int ans = 1; + auto check = [](string& s, string& t) -> bool { + int m = s.size(), n = t.size(); + int i = 0, j = 0; + while (i < m && j < n) { + if (s[i] == t[j]) { + ++i; + } + ++j; + } + return i == m; + }; + for (int i = 0; i < n; ++i) { + f[i] = 1; + auto w = words[i]; + for (int j : g[w.size() - 1]) { + if (check(words[j], w)) { + f[i] = max(f[i], f[j] + 1); + ans = max(ans, f[i]); + } + } + g[w.size()].push_back(i); + } + return ans; + } +}; +``` + +```cpp +class Solution { +public: + int longestStrChain(vector& words) { + sort(words.begin(), words.end(), [](auto& a, auto& b) { return a.size() < b.size(); }); + int ans = 0; + unordered_map d; + for (auto& s : words) { int x = 1; - for (int i = 0; i < word.size(); ++i) { - string pre = word.substr(0, i) + word.substr(i + 1); - x = max(x, map[pre] + 1); + for (int i = 0; i < s.size(); ++i) { + string t = s.substr(0, i) + s.substr(i + 1); + x = max(x, d[t] + 1); } - map[word] = x; - res = max(res, x); + d[s] = x; + ans = max(ans, x); } - return res; + return ans; } }; ``` @@ -170,18 +231,56 @@ public: ```go func longestStrChain(words []string) int { sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) - res := 0 - mp := make(map[string]int) - for _, word := range words { + n := len(words) + f := make([]int, n) + g := [17][]int{} + ans := 1 + check := func(s, t string) bool { + m, n := len(s), len(t) + i, j := 0, 0 + for i < m && j < n { + if s[i] == t[j] { + i++ + } + j++ + } + return i == m + } + for i, w := range words { + f[i] = 1 + for _, j := range g[len(w)-1] { + if check(words[j], w) { + f[i] = max(f[i], f[j]+1) + ans = max(ans, f[i]) + } + } + g[len(w)] = append(g[len(w)], i) + } + return ans +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} +``` + +```go +func longestStrChain(words []string) (ans int) { + sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) + d := map[string]int{} + for _, s := range words { x := 1 - for i := 0; i < len(word); i++ { - pre := word[0:i] + word[i+1:len(word)] - x = max(x, mp[pre]+1) + for i := 0; i < len(s); i++ { + t := s[:i] + s[i+1:] + x = max(x, d[t]+1) } - mp[word] = x - res = max(res, x) + d[s] = x + ans = max(ans, x) } - return res + return } func max(a, b int) int { @@ -192,6 +291,60 @@ func max(a, b int) int { } ``` +### **TypeScript** + +```ts +function longestStrChain(words: string[]): number { + words.sort((a, b) => a.length - b.length); + let ans = 1; + const n = words.length; + const f: number[] = new Array(n).fill(1); + const g: number[][] = new Array(17).fill(0).map(() => []); + const check = (s: string, t: string): boolean => { + const m = s.length; + const n = t.length; + let i = 0; + let j = 0; + while (i < m && j < n) { + if (s[i] === t[j]) { + ++i; + } + ++j; + } + return i === m; + }; + for (let i = 0; i < n; ++i) { + const w = words[i]; + for (const j of g[w.length - 1]) { + if (check(words[j], w)) { + f[i] = Math.max(f[i], f[j] + 1); + ans = Math.max(ans, f[i]); + } + } + g[w.length].push(i); + } + return ans; +} +``` + +```ts +function longestStrChain(words: string[]): number { + words.sort((a, b) => a.length - b.length); + let ans = 0; + const d: Map = new Map(); + for (const s of words) { + let x = 1; + for (let i = 0; i < s.length; ++i) { + const t = s.slice(0, i) + s.slice(i + 1); + x = Math.max(x, (d.get(t) || 0) + 1); + } + d.set(s, x); + ans = Math.max(ans, x); + } + return ans; +} +``` + ### **...** ``` diff --git a/solution/1000-1099/1048.Longest String Chain/Solution.cpp b/solution/1000-1099/1048.Longest String Chain/Solution.cpp index bdafcd5465f97..9fed2da34baec 100644 --- a/solution/1000-1099/1048.Longest String Chain/Solution.cpp +++ b/solution/1000-1099/1048.Longest String Chain/Solution.cpp @@ -1,18 +1,18 @@ class Solution { public: int longestStrChain(vector& words) { - sort(words.begin(), words.end(), [&](string a, string b) { return a.size() < b.size(); }); - int res = 0; - unordered_map map; - for (auto word : words) { + sort(words.begin(), words.end(), [](auto& a, auto& b) { return a.size() < b.size(); }); + int ans = 0; + unordered_map d; + for (auto& s : words) { int x = 1; - for (int i = 0; i < word.size(); ++i) { - string pre = word.substr(0, i) + word.substr(i + 1); - x = max(x, map[pre] + 1); + for (int i = 0; i < s.size(); ++i) { + string t = s.substr(0, i) + s.substr(i + 1); + x = max(x, d[t] + 1); } - map[word] = x; - res = max(res, x); + d[s] = x; + ans = max(ans, x); } - return res; + return ans; } }; \ No newline at end of file diff --git a/solution/1000-1099/1048.Longest String Chain/Solution.go b/solution/1000-1099/1048.Longest String Chain/Solution.go index 2c42f70088737..adfaf46e56e58 100644 --- a/solution/1000-1099/1048.Longest String Chain/Solution.go +++ b/solution/1000-1099/1048.Longest String Chain/Solution.go @@ -1,17 +1,16 @@ -func longestStrChain(words []string) int { +func longestStrChain(words []string) (ans int) { sort.Slice(words, func(i, j int) bool { return len(words[i]) < len(words[j]) }) - res := 0 - mp := make(map[string]int) - for _, word := range words { + d := map[string]int{} + for _, s := range words { x := 1 - for i := 0; i < len(word); i++ { - pre := word[0:i] + word[i+1:len(word)] - x = max(x, mp[pre]+1) + for i := 0; i < len(s); i++ { + t := s[:i] + s[i+1:] + x = max(x, d[t]+1) } - mp[word] = x - res = max(res, x) + d[s] = x + ans = max(ans, x) } - return res + return } func max(a, b int) int { diff --git a/solution/1000-1099/1048.Longest String Chain/Solution.java b/solution/1000-1099/1048.Longest String Chain/Solution.java index 6c282de062bf1..5f930b1d69f65 100644 --- a/solution/1000-1099/1048.Longest String Chain/Solution.java +++ b/solution/1000-1099/1048.Longest String Chain/Solution.java @@ -1,17 +1,17 @@ class Solution { public int longestStrChain(String[] words) { Arrays.sort(words, Comparator.comparingInt(String::length)); - int res = 0; - Map map = new HashMap<>(); - for (String word : words) { - int x = 1; - for (int i = 0; i < word.length(); ++i) { - String pre = word.substring(0, i) + word.substring(i + 1); - x = Math.max(x, map.getOrDefault(pre, 0) + 1); + Map d = new HashMap<>(); + int ans = 0; + for (String s : words) { + int x = 0; + for (int i = 0; i < s.length(); ++i) { + String t = s.substring(0, i) + s.substring(i + 1); + x = Math.max(x, d.getOrDefault(t, 0) + 1); } - map.put(word, x); - res = Math.max(res, x); + d.put(s, x); + ans = Math.max(ans, x); } - return res; + return ans; } } \ No newline at end of file diff --git a/solution/1000-1099/1048.Longest String Chain/Solution.py b/solution/1000-1099/1048.Longest String Chain/Solution.py index 7c4cd69d3e7ee..d9d8364550846 100644 --- a/solution/1000-1099/1048.Longest String Chain/Solution.py +++ b/solution/1000-1099/1048.Longest String Chain/Solution.py @@ -1,24 +1,13 @@ class Solution: def longestStrChain(self, words: List[str]) -> int: - def check(w1, w2): - if len(w2) - len(w1) != 1: - return False - i = j = cnt = 0 - while i < len(w1) and j < len(w2): - if w1[i] != w2[j]: - cnt += 1 - else: - i += 1 - j += 1 - return cnt < 2 and i == len(w1) - - n = len(words) - dp = [1] * (n + 1) - words.sort(key=lambda x: len(x)) - res = 1 - for i in range(1, n): - for j in range(i): - if check(words[j], words[i]): - dp[i] = max(dp[i], dp[j] + 1) - res = max(res, dp[i]) - return res + words.sort(key=len) + d = defaultdict(int) + ans = 0 + for s in words: + x = 1 + for i in range(len(s)): + t = s[:i] + s[i + 1:] + x = max(x, d[t] + 1) + d[s] = x + ans = max(ans, x) + return ans diff --git a/solution/1000-1099/1048.Longest String Chain/Solution.ts b/solution/1000-1099/1048.Longest String Chain/Solution.ts index e6f9f29496b31..a5793b782c6b4 100644 --- a/solution/1000-1099/1048.Longest String Chain/Solution.ts +++ b/solution/1000-1099/1048.Longest String Chain/Solution.ts @@ -1,15 +1,15 @@ function longestStrChain(words: string[]): number { words.sort((a, b) => a.length - b.length); let ans = 0; - let hashTable = new Map(); - for (let word of words) { - let c = 1; - for (let i = 0; i < word.length; i++) { - let pre = word.substring(0, i) + word.substring(i + 1); - c = Math.max(c, (hashTable.get(pre) || 0) + 1); + const d: Map = new Map(); + for (const s of words) { + let x = 1; + for (let i = 0; i < s.length; ++i) { + const t = s.slice(0, i) + s.slice(i + 1); + x = Math.max(x, (d.get(t) || 0) + 1); } - hashTable.set(word, c); - ans = Math.max(ans, c); + d.set(s, x); + ans = Math.max(ans, x); } return ans; } diff --git a/solution/1100-1199/1163.Last Substring in Lexicographical Order/README_EN.md b/solution/1100-1199/1163.Last Substring in Lexicographical Order/README_EN.md index c0bd384c7ff2f..2c830536946cb 100644 --- a/solution/1100-1199/1163.Last Substring in Lexicographical Order/README_EN.md +++ b/solution/1100-1199/1163.Last Substring in Lexicographical Order/README_EN.md @@ -32,7 +32,7 @@ ## Solutions -**Approach 1: Two pointers** +**Solution 1: Two pointers** We notice that if a substring starts from position $i$, then the largest substring with the largest dictionary order must be $s[i,..n-1]$, which is the longest suffix starting from position $i$. Therefore, we only need to find the largest suffix substring. diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/README.md b/solution/1200-1299/1259.Handshakes That Don't Cross/README.md index b2d824bcfc480..46fdb52492826 100644 --- a/solution/1200-1299/1259.Handshakes That Don't Cross/README.md +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/README.md @@ -56,6 +56,22 @@ +**方法一:动态规划** + +我们定义 $f[i]$ 表示 $i$ 个人的握手方案数,初始时 $f[0]=1$,答案为 $f[numPeople]$。 + +考虑 $f[i]$,其中 $i \in [2,4,6,\cdots,numPeople]$,我们可以在顺时针方向上枚举第一个人跳过的人数 $j$,即第一个人跳过了 $j$ 个人去与另一个人握手,这里跳过的人数 $j$ 必须是偶数,所以 $j \in [0,2,4,\cdots,i-2]$,那么跳过的人的握手方案数为 $f[j]$,剩下的人数为 $k=i-j-2$,握手方案数为 $f[k]$,将这两部分相乘,再累加到 $f[i]$ 上即可,状态转移方程为: + +$$ +f[i] = \sum_{j=0}^{i-2} f[j] \times f[i-j-2] +$$ + +其中 $i \in [2,4,6,\cdots,numPeople]$,而 $j$ 为偶数,且 $j \in [0,2,4,\cdots,i-2]$。 + +最后答案即为 $f[numPeople]$。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n)$。其中 $n$ 为总人数。 + ### **Python3** @@ -63,7 +79,16 @@ ```python - +class Solution: + def numberOfWays(self, numPeople: int) -> int: + mod = 10**9 + 7 + f = [0] * (numPeople + 1) + f[0] = 1 + for i in range(2, numPeople + 1, 2): + for j in range(0, i - 1, 2): + k = i - j - 2 + f[i] = (f[i] + f[j] * f[k]) % mod + return f[numPeople] ``` ### **Java** @@ -71,7 +96,75 @@ ```java +class Solution { + public int numberOfWays(int numPeople) { + final int mod = (int) 1e9 + 7; + long[] f = new long[numPeople + 1]; + f[0] = 1; + for (int i = 2; i <= numPeople; i += 2) { + for (int j = 0; j < i - 1; j += 2) { + int k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return (int) f[numPeople]; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numberOfWays(int numPeople) { + const int mod = 1e9 + 7; + long long f[numPeople + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + for (int i = 2; i <= numPeople; i += 2) { + for (int j = 0; j < i - 1; j += 2) { + int k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return f[numPeople]; + } +}; +``` + +### **Go** + +```go +func numberOfWays(numPeople int) int { + const mod int = 1e9 + 7 + f := make([]int, numPeople+1) + f[0] = 1 + for i := 2; i <= numPeople; i += 2 { + for j := 0; j < i-1; j += 2 { + k := i - j - 2 + f[i] = (f[i] + f[j]*f[k]) % mod + } + } + return f[numPeople] +} +``` +### **TypeScript** + +```ts +function numberOfWays(numPeople: number): number { + const mod = BigInt(10 ** 9 + 7); + const f: bigint[] = new Array(numPeople + 1).fill(0n); + f[0] = 1n; + for (let i = 2; i <= numPeople; i += 2) { + for (let j = 0; j < i - 1; j += 2) { + const k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return Number(f[numPeople]); +} ``` ### **...** diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/README_EN.md b/solution/1200-1299/1259.Handshakes That Don't Cross/README_EN.md index 497c113766b86..57c7434233cfd 100644 --- a/solution/1200-1299/1259.Handshakes That Don't Cross/README_EN.md +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/README_EN.md @@ -36,18 +36,111 @@ ## Solutions +**Solution 1: Dynamic Programming** + +We define $f[i]$ as the number of handshake schemes for $i$ people, and $f[0]=1$ at the beginning, the answer is $f[numPeople]$. + +Considering $f[i]$, where $i \in [2,4,6,\cdots,numPeople]$, we can enumerate the number of people skipped by the first person in the clockwise direction, that is, the first person skipped $j$ people to shake hands with another person, where the number of people skipped $j$ must be even, so $j \in [0,2,4,\cdots,i-2]$, then the handshake scheme of the skipped people is $f[j]$, and the remaining number of people is $k=i-j-2$, the handshake scheme is $f[k]$, multiply these two parts and add them to $f[i]$, the state transition equation is: + +$$ +f[i] = \sum_{j=0}^{i-2} f[j] \times f[i-j-2] +$$ + +where $i \in [2,4,6,\cdots,numPeople]$, and $j$ is even, and $j \in [0,2,4,\cdots,i-2]$. + +Finally, the answer is $f[numPeople]$. + +The time complexity is $O(n^2)$, and the space complexity is $O(n)$. Where $n$ is the total number of people. + ### **Python3** ```python - +class Solution: + def numberOfWays(self, numPeople: int) -> int: + mod = 10**9 + 7 + f = [0] * (numPeople + 1) + f[0] = 1 + for i in range(2, numPeople + 1, 2): + for j in range(0, i - 1, 2): + k = i - j - 2 + f[i] = (f[i] + f[j] * f[k]) % mod + return f[numPeople] ``` ### **Java** ```java +class Solution { + public int numberOfWays(int numPeople) { + final int mod = (int) 1e9 + 7; + long[] f = new long[numPeople + 1]; + f[0] = 1; + for (int i = 2; i <= numPeople; i += 2) { + for (int j = 0; j < i - 1; j += 2) { + int k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return (int) f[numPeople]; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numberOfWays(int numPeople) { + const int mod = 1e9 + 7; + long long f[numPeople + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + for (int i = 2; i <= numPeople; i += 2) { + for (int j = 0; j < i - 1; j += 2) { + int k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return f[numPeople]; + } +}; +``` + +### **Go** + +```go +func numberOfWays(numPeople int) int { + const mod int = 1e9 + 7 + f := make([]int, numPeople+1) + f[0] = 1 + for i := 2; i <= numPeople; i += 2 { + for j := 0; j < i-1; j += 2 { + k := i - j - 2 + f[i] = (f[i] + f[j]*f[k]) % mod + } + } + return f[numPeople] +} +``` +### **TypeScript** + +```ts +function numberOfWays(numPeople: number): number { + const mod = BigInt(10 ** 9 + 7); + const f: bigint[] = new Array(numPeople + 1).fill(0n); + f[0] = 1n; + for (let i = 2; i <= numPeople; i += 2) { + for (let j = 0; j < i - 1; j += 2) { + const k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return Number(f[numPeople]); +} ``` ### **...** diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.cpp b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.cpp new file mode 100644 index 0000000000000..8e62813569571 --- /dev/null +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.cpp @@ -0,0 +1,16 @@ +class Solution { +public: + int numberOfWays(int numPeople) { + const int mod = 1e9 + 7; + long long f[numPeople + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + for (int i = 2; i <= numPeople; i += 2) { + for (int j = 0; j < i - 1; j += 2) { + int k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return f[numPeople]; + } +}; \ No newline at end of file diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.go b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.go new file mode 100644 index 0000000000000..e4bc810bc01b4 --- /dev/null +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.go @@ -0,0 +1,12 @@ +func numberOfWays(numPeople int) int { + const mod int = 1e9 + 7 + f := make([]int, numPeople+1) + f[0] = 1 + for i := 2; i <= numPeople; i += 2 { + for j := 0; j < i-1; j += 2 { + k := i - j - 2 + f[i] = (f[i] + f[j]*f[k]) % mod + } + } + return f[numPeople] +} \ No newline at end of file diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.java b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.java new file mode 100644 index 0000000000000..31691cfe01edb --- /dev/null +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.java @@ -0,0 +1,14 @@ +class Solution { + public int numberOfWays(int numPeople) { + final int mod = (int) 1e9 + 7; + long[] f = new long[numPeople + 1]; + f[0] = 1; + for (int i = 2; i <= numPeople; i += 2) { + for (int j = 0; j < i - 1; j += 2) { + int k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return (int) f[numPeople]; + } +} \ No newline at end of file diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.py b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.py new file mode 100644 index 0000000000000..9522437214b7b --- /dev/null +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.py @@ -0,0 +1,10 @@ +class Solution: + def numberOfWays(self, numPeople: int) -> int: + mod = 10**9 + 7 + f = [0] * (numPeople + 1) + f[0] = 1 + for i in range(2, numPeople + 1, 2): + for j in range(0, i - 1, 2): + k = i - j - 2 + f[i] = (f[i] + f[j] * f[k]) % mod + return f[numPeople] diff --git a/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.ts b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.ts new file mode 100644 index 0000000000000..d54236399d009 --- /dev/null +++ b/solution/1200-1299/1259.Handshakes That Don't Cross/Solution.ts @@ -0,0 +1,12 @@ +function numberOfWays(numPeople: number): number { + const mod = BigInt(10 ** 9 + 7); + const f: bigint[] = new Array(numPeople + 1).fill(0n); + f[0] = 1n; + for (let i = 2; i <= numPeople; i += 2) { + for (let j = 0; j < i - 1; j += 2) { + const k = i - j - 2; + f[i] = (f[i] + f[j] * f[k]) % mod; + } + } + return Number(f[numPeople]); +} diff --git a/solution/1400-1499/1416.Restore The Array/README.md b/solution/1400-1499/1416.Restore The Array/README.md index 0127d6830d7a6..fd45bdf313e58 100644 --- a/solution/1400-1499/1416.Restore The Array/README.md +++ b/solution/1400-1499/1416.Restore The Array/README.md @@ -64,6 +64,32 @@ +**方法一:记忆化搜索** + +我们设计一个函数 $dfs(i)$,表示从字符串的第 $i$ 个字符开始恢复数组的方案数。那么答案就是 $dfs(0)$。 + +函数 $dfs(i)$ 的执行逻辑如下: + +- 如果 $i$ 超出了字符串的长度,说明我们已经恢复了整个数组,方案数为 $1$。 +- 如果 $i$ 对应的字符为 $0$,那么无法恢复出任何整数,方案数为 $0$。 +- 否则,我们枚举从 $i$ 开始的连续若干个字符 $s[i..j]$,将其解析成一个整数 $x$,如果 $x$ 不超过 $k$,那么我们就可以从 $j+1$ 开始继续恢复数组,方案数为 $dfs(j+1)$。我们对所有的 $x$ 的方案数求和,即为 $dfs(i)$ 的值。 + +最后返回 $dfs(0)$ 即可。 + +为了避免重复计算,我们可以使用记忆化的方法进行优化。我们用一个数组 $f$ 记录所有的 $dfs(i)$ 的值,当我们需要计算 $dfs(i)$ 时,如果 $f[i]$ 已经被计算出来了,那么我们直接返回 $f[i]$ 即可。 + +时间复杂度 $(n \times \log k)$,空间复杂度 $O(n)$。其中 $n$ 是字符串的长度,而 $k$ 是题目给定的整数 $k$。 + +**方法二:动态规划** + +我们也可以使用动态规划的方法计算答案。 + +我们定义 $f[i]$ 表示将字符串 $s$ 的前 $i$ 个字符恢复成一个整数的方案数。初始时 $f[0]=1$,答案为 $f[n]$。 + +考虑 $f[i]$,其中 $i \in [1,n]$。我们可以从大到小枚举 $j$,其中 $j \in [1,i]$,如果 $s[j-1..i-1]$ 对应的整数 $x$ 不超过 $k$,且 $s[j-1] \neq '0'$,那么我们就可以用 $f[j-1]$ 来更新 $f[i]$,即 $f[i] = f[i] + f[j-1]$。在计算出所有的 $f[i]$ 之后,答案即为 $f[n]$。 + +时间复杂度 $O(n \times \log k)$,空间复杂度 $O(n)$。其中 $n$ 是字符串的长度,而 $k$ 是题目给定的整数 $k$。 + ### **Python3** @@ -71,7 +97,43 @@ ```python +class Solution: + def numberOfArrays(self, s: str, k: int) -> int: + @cache + def dfs(i: int): + if i >= n: + return 1 + if s[i] == '0': + return 0 + ans = x = 0 + for j in range(i, n): + x = x * 10 + int(s[j]) + if x > k: + break + ans = (ans + dfs(j + 1)) % mod + return ans + + n = len(s) + mod = 10**9 + 7 + return dfs(0) +``` +```python +class Solution: + def numberOfArrays(self, s: str, k: int) -> int: + n = len(s) + f = [1] + [0] * n + mod = 10**9 + 7 + for i in range(1, n + 1): + x, p = 0, 1 + for j in range(i, max(0, i - 11), -1): + x = int(s[j - 1]) * p + x + if x > k: + break + if s[j - 1] != '0': + f[i] = (f[i] + f[j - 1]) % mod + p *= 10 + return f[n] ``` ### **Java** @@ -79,7 +141,246 @@ ```java +class Solution { + private Integer[] f; + private String s; + private int n; + private int k; + + public int numberOfArrays(String s, int k) { + n = s.length(); + this.s = s; + this.k = k; + f = new Integer[n]; + return dfs(0); + } + + private int dfs(int i) { + if (i >= n) { + return 1; + } + if (s.charAt(i) == '0') { + return 0; + } + if (f[i] != null) { + return f[i]; + } + int ans = 0; + long x = 0; + final int mod = (int) 1e9 + 7; + for (int j = i; j < n; ++j) { + x = x * 10 + s.charAt(j) - '0'; + if (x > k) { + break; + } + ans = (ans + dfs(j + 1)) % mod; + } + return f[i] = ans; + } +} +``` + +```java +class Solution { + public int numberOfArrays(String s, int k) { + int n = s.length(); + int[] f = new int[n + 1]; + f[0] = 1; + final int mod = (int) 1e9 + 7; + for (int i = 1; i <= n; ++i) { + long x = 0, p = 1; + for (int j = i; j > Math.max(i - 11, 0); --j) { + x = (s.charAt(j - 1) - '0') * p + x; + if (x > k) { + break; + } + if (s.charAt(j - 1) != '0') { + f[i] = (f[i] + f[j - 1]) % mod; + } + p *= 10; + } + } + return f[n]; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numberOfArrays(string s, int k) { + int n = s.size(); + int f[n]; + memset(f, -1, sizeof(f)); + const int mod = 1e9 + 7; + function dfs = [&](int i) -> int { + if (i >= n) { + return 1; + } + if (s[i] == '0') { + return 0; + } + if (f[i] != -1) { + return f[i]; + } + int ans = 0; + long long x = 0; + for (int j = i; j < n; ++j) { + x = x * 10 + s[j] - '0'; + if (x > k) { + break; + } + ans = (ans + dfs(j + 1)) % mod; + } + return f[i] = ans; + }; + return dfs(0); + } +}; +``` + +```cpp +class Solution { +public: + int numberOfArrays(string s, int k) { + int n = s.size(); + int f[n + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + const int mod = 1e9 + 7; + for (int i = 1; i <= n; ++i) { + long x = 0, p = 1; + for (int j = i; j > max(i - 11, 0); --j) { + x = (s[j - 1] - '0') * p + x; + if (x > k) { + break; + } + if (s[j - 1] != '0') { + f[i] = (f[i] + f[j - 1]) % mod; + } + p *= 10; + } + } + return f[n]; + } +}; +``` + +### **Go** + +```go +func numberOfArrays(s string, k int) int { + n := len(s) + f := make([]int, n) + for i := range f { + f[i] = -1 + } + const mod int = 1e9 + 7 + var dfs func(int) int + dfs = func(i int) int { + if i >= n { + return 1 + } + if s[i] == '0' { + return 0 + } + if f[i] != -1 { + return f[i] + } + ans, x := 0, 0 + for j := i; j < n; j++ { + x = x*10 + int(s[j]-'0') + if x > k { + break + } + ans = (ans + dfs(j+1)) % mod + } + f[i] = ans + return ans + } + return dfs(0) +} +``` + +```go +func numberOfArrays(s string, k int) int { + n := len(s) + f := make([]int, n+1) + f[0] = 1 + const mod int = 1e9 + 7 + for i := 1; i <= n; i++ { + x, p := 0, 1 + for j := i; j > i-11 && j > 0; j-- { + x = int(s[j-1]-'0')*p + x + if x > k { + break + } + if s[j-1] != '0' { + f[i] = (f[i] + f[j-1]) % mod + } + p *= 10 + } + } + return f[n] +} +``` + +### **TypeScript** + +```ts +function numberOfArrays(s: string, k: number): number { + const n = s.length; + const f: number[] = new Array(n + 1).fill(-1); + const dfs = (i: number): number => { + if (i >= n) { + return 1; + } + if (s[i] === '0') { + return 0; + } + if (f[i] !== -1) { + return f[i]; + } + let x = 0; + let ans = 0; + for (let j = i; j < n; ++j) { + x = x * 10 + s[j].charCodeAt(0) - '0'.charCodeAt(0); + if (x > k) { + break; + } + ans += dfs(j + 1); + ans %= 1000000007; + } + return (f[i] = ans); + }; + return dfs(0); +} +``` +```ts +function numberOfArrays(s: string, k: number): number { + const n = s.length; + const f: number[] = new Array(n + 1).fill(0); + f[0] = 1; + for (let i = 1; i <= n; ++i) { + let x = 0; + let p = 1; + for (let j = i; j > Math.max(0, i - 11); --j) { + x = (s[j - 1].charCodeAt(0) - '0'.charCodeAt(0)) * p + x; + if (x > k) { + break; + } + if (s[j - 1] !== '0') { + f[i] += f[j - 1]; + f[i] %= 1000000007; + } + p *= 10; + } + } + return f[n]; +} ``` ### **...** diff --git a/solution/1400-1499/1416.Restore The Array/README_EN.md b/solution/1400-1499/1416.Restore The Array/README_EN.md index f11340ddd518e..2114090358e9b 100644 --- a/solution/1400-1499/1416.Restore The Array/README_EN.md +++ b/solution/1400-1499/1416.Restore The Array/README_EN.md @@ -49,13 +49,288 @@ ### **Python3** ```python +class Solution: + def numberOfArrays(self, s: str, k: int) -> int: + @cache + def dfs(i: int): + if i >= n: + return 1 + if s[i] == '0': + return 0 + ans = x = 0 + for j in range(i, n): + x = x * 10 + int(s[j]) + if x > k: + break + ans = (ans + dfs(j + 1)) % mod + return ans + n = len(s) + mod = 10**9 + 7 + return dfs(0) +``` + +```python +class Solution: + def numberOfArrays(self, s: str, k: int) -> int: + n = len(s) + f = [1] + [0] * n + mod = 10**9 + 7 + for i in range(1, n + 1): + x, p = 0, 1 + for j in range(i, max(0, i - 11), -1): + x = int(s[j - 1]) * p + x + if x > k: + break + if s[j - 1] != '0': + f[i] = (f[i] + f[j - 1]) % mod + p *= 10 + return f[n] ``` ### **Java** ```java +class Solution { + private Integer[] f; + private String s; + private int n; + private int k; + + public int numberOfArrays(String s, int k) { + n = s.length(); + this.s = s; + this.k = k; + f = new Integer[n]; + return dfs(0); + } + + private int dfs(int i) { + if (i >= n) { + return 1; + } + if (s.charAt(i) == '0') { + return 0; + } + if (f[i] != null) { + return f[i]; + } + int ans = 0; + long x = 0; + final int mod = (int) 1e9 + 7; + for (int j = i; j < n; ++j) { + x = x * 10 + s.charAt(j) - '0'; + if (x > k) { + break; + } + ans = (ans + dfs(j + 1)) % mod; + } + return f[i] = ans; + } +} +``` + +```java +class Solution { + public int numberOfArrays(String s, int k) { + int n = s.length(); + int[] f = new int[n + 1]; + f[0] = 1; + final int mod = (int) 1e9 + 7; + for (int i = 1; i <= n; ++i) { + long x = 0, p = 1; + for (int j = i; j > Math.max(i - 11, 0); --j) { + x = (s.charAt(j - 1) - '0') * p + x; + if (x > k) { + break; + } + if (s.charAt(j - 1) != '0') { + f[i] = (f[i] + f[j - 1]) % mod; + } + p *= 10; + } + } + return f[n]; + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + int numberOfArrays(string s, int k) { + int n = s.size(); + int f[n]; + memset(f, -1, sizeof(f)); + const int mod = 1e9 + 7; + function dfs = [&](int i) -> int { + if (i >= n) { + return 1; + } + if (s[i] == '0') { + return 0; + } + if (f[i] != -1) { + return f[i]; + } + int ans = 0; + long long x = 0; + for (int j = i; j < n; ++j) { + x = x * 10 + s[j] - '0'; + if (x > k) { + break; + } + ans = (ans + dfs(j + 1)) % mod; + } + return f[i] = ans; + }; + return dfs(0); + } +}; +``` + +```cpp +class Solution { +public: + int numberOfArrays(string s, int k) { + int n = s.size(); + int f[n + 1]; + memset(f, 0, sizeof(f)); + f[0] = 1; + const int mod = 1e9 + 7; + for (int i = 1; i <= n; ++i) { + long x = 0, p = 1; + for (int j = i; j > max(i - 11, 0); --j) { + x = (s[j - 1] - '0') * p + x; + if (x > k) { + break; + } + if (s[j - 1] != '0') { + f[i] = (f[i] + f[j - 1]) % mod; + } + p *= 10; + } + } + return f[n]; + } +}; +``` + +### **Go** + +```go +func numberOfArrays(s string, k int) int { + n := len(s) + f := make([]int, n) + for i := range f { + f[i] = -1 + } + const mod int = 1e9 + 7 + var dfs func(int) int + dfs = func(i int) int { + if i >= n { + return 1 + } + if s[i] == '0' { + return 0 + } + if f[i] != -1 { + return f[i] + } + ans, x := 0, 0 + for j := i; j < n; j++ { + x = x*10 + int(s[j]-'0') + if x > k { + break + } + ans = (ans + dfs(j+1)) % mod + } + f[i] = ans + return ans + } + return dfs(0) +} +``` + +```go +func numberOfArrays(s string, k int) int { + n := len(s) + f := make([]int, n+1) + f[0] = 1 + const mod int = 1e9 + 7 + for i := 1; i <= n; i++ { + x, p := 0, 1 + for j := i; j > i-11 && j > 0; j-- { + x = int(s[j-1]-'0')*p + x + if x > k { + break + } + if s[j-1] != '0' { + f[i] = (f[i] + f[j-1]) % mod + } + p *= 10 + } + } + return f[n] +} +``` + +### **TypeScript** + +```ts +function numberOfArrays(s: string, k: number): number { + const n = s.length; + const f: number[] = new Array(n + 1).fill(-1); + const dfs = (i: number): number => { + if (i >= n) { + return 1; + } + if (s[i] === '0') { + return 0; + } + if (f[i] !== -1) { + return f[i]; + } + let x = 0; + let ans = 0; + for (let j = i; j < n; ++j) { + x = x * 10 + s[j].charCodeAt(0) - '0'.charCodeAt(0); + if (x > k) { + break; + } + ans += dfs(j + 1); + ans %= 1000000007; + } + return (f[i] = ans); + }; + return dfs(0); +} +``` +```ts +function numberOfArrays(s: string, k: number): number { + const n = s.length; + const f: number[] = new Array(n + 1).fill(0); + f[0] = 1; + for (let i = 1; i <= n; ++i) { + let x = 0; + let p = 1; + for (let j = i; j > Math.max(0, i - 11); --j) { + x = (s[j - 1].charCodeAt(0) - '0'.charCodeAt(0)) * p + x; + if (x > k) { + break; + } + if (s[j - 1] !== '0') { + f[i] += f[j - 1]; + f[i] %= 1000000007; + } + p *= 10; + } + } + return f[n]; +} ``` ### **...** diff --git a/solution/1400-1499/1416.Restore The Array/Solution.cpp b/solution/1400-1499/1416.Restore The Array/Solution.cpp new file mode 100644 index 0000000000000..6bff5ff6427ad --- /dev/null +++ b/solution/1400-1499/1416.Restore The Array/Solution.cpp @@ -0,0 +1,31 @@ +class Solution { +public: + int numberOfArrays(string s, int k) { + int n = s.size(); + int f[n]; + memset(f, -1, sizeof(f)); + const int mod = 1e9 + 7; + function dfs = [&](int i) -> int { + if (i >= n) { + return 1; + } + if (s[i] == '0') { + return 0; + } + if (f[i] != -1) { + return f[i]; + } + int ans = 0; + long long x = 0; + for (int j = i; j < n; ++j) { + x = x * 10 + s[j] - '0'; + if (x > k) { + break; + } + ans = (ans + dfs(j + 1)) % mod; + } + return f[i] = ans; + }; + return dfs(0); + } +}; \ No newline at end of file diff --git a/solution/1400-1499/1416.Restore The Array/Solution.go b/solution/1400-1499/1416.Restore The Array/Solution.go new file mode 100644 index 0000000000000..3860c58badc33 --- /dev/null +++ b/solution/1400-1499/1416.Restore The Array/Solution.go @@ -0,0 +1,31 @@ +func numberOfArrays(s string, k int) int { + n := len(s) + f := make([]int, n) + for i := range f { + f[i] = -1 + } + const mod int = 1e9 + 7 + var dfs func(int) int + dfs = func(i int) int { + if i >= n { + return 1 + } + if s[i] == '0' { + return 0 + } + if f[i] != -1 { + return f[i] + } + ans, x := 0, 0 + for j := i; j < n; j++ { + x = x*10 + int(s[j]-'0') + if x > k { + break + } + ans = (ans + dfs(j+1)) % mod + } + f[i] = ans + return ans + } + return dfs(0) +} \ No newline at end of file diff --git a/solution/1400-1499/1416.Restore The Array/Solution.java b/solution/1400-1499/1416.Restore The Array/Solution.java new file mode 100644 index 0000000000000..e3b5e01278491 --- /dev/null +++ b/solution/1400-1499/1416.Restore The Array/Solution.java @@ -0,0 +1,37 @@ +class Solution { + private Integer[] f; + private String s; + private int n; + private int k; + + public int numberOfArrays(String s, int k) { + n = s.length(); + this.s = s; + this.k = k; + f = new Integer[n]; + return dfs(0); + } + + private int dfs(int i) { + if (i >= n) { + return 1; + } + if (s.charAt(i) == '0') { + return 0; + } + if (f[i] != null) { + return f[i]; + } + int ans = 0; + long x = 0; + final int mod = (int) 1e9 + 7; + for (int j = i; j < n; ++j) { + x = x * 10 + s.charAt(j) - '0'; + if (x > k) { + break; + } + ans = (ans + dfs(j + 1)) % mod; + } + return f[i] = ans; + } +} \ No newline at end of file diff --git a/solution/1400-1499/1416.Restore The Array/Solution.py b/solution/1400-1499/1416.Restore The Array/Solution.py new file mode 100644 index 0000000000000..02fd11916c6a2 --- /dev/null +++ b/solution/1400-1499/1416.Restore The Array/Solution.py @@ -0,0 +1,19 @@ +class Solution: + def numberOfArrays(self, s: str, k: int) -> int: + @cache + def dfs(i: int): + if i >= n: + return 1 + if s[i] == '0': + return 0 + ans = x = 0 + for j in range(i, n): + x = x * 10 + int(s[j]) + if x > k: + break + ans = (ans + dfs(j + 1)) % mod + return ans + + n = len(s) + mod = 10**9 + 7 + return dfs(0) diff --git a/solution/1400-1499/1416.Restore The Array/Solution.ts b/solution/1400-1499/1416.Restore The Array/Solution.ts new file mode 100644 index 0000000000000..798c945adc694 --- /dev/null +++ b/solution/1400-1499/1416.Restore The Array/Solution.ts @@ -0,0 +1,27 @@ +function numberOfArrays(s: string, k: number): number { + const n = s.length; + const f: number[] = new Array(n + 1).fill(-1); + const dfs = (i: number): number => { + if (i >= n) { + return 1; + } + if (s[i] === '0') { + return 0; + } + if (f[i] !== -1) { + return f[i]; + } + let x = 0; + let ans = 0; + for (let j = i; j < n; ++j) { + x = x * 10 + s[j].charCodeAt(0) - '0'.charCodeAt(0); + if (x > k) { + break; + } + ans += dfs(j + 1); + ans %= 1000000007; + } + return (f[i] = ans); + }; + return dfs(0); +} diff --git a/solution/1400-1499/1480.Running Sum of 1d Array/README_EN.md b/solution/1400-1499/1480.Running Sum of 1d Array/README_EN.md index 3ea2ea004cce5..57e4e058cee37 100644 --- a/solution/1400-1499/1480.Running Sum of 1d Array/README_EN.md +++ b/solution/1400-1499/1480.Running Sum of 1d Array/README_EN.md @@ -51,7 +51,7 @@ ## Solutions -**Approach 1: Prefix Sum** +**Solution 1: Prefix Sum** We directly traverse the array. For the current element $nums[i]$, we add it with the prefix sum $nums[i-1]$ to get the prefix sum $nums[i]$ of the current element. diff --git a/solution/1400-1499/1481.Least Number of Unique Integers after K Removals/README_EN.md b/solution/1400-1499/1481.Least Number of Unique Integers after K Removals/README_EN.md index 562389012925f..aefdc4bd28ddd 100644 --- a/solution/1400-1499/1481.Least Number of Unique Integers after K Removals/README_EN.md +++ b/solution/1400-1499/1481.Least Number of Unique Integers after K Removals/README_EN.md @@ -46,7 +46,7 @@ ## Solutions -**Approach 1: Hash Table + Sorting** +**Solution 1: Hash Table + Sorting** We use the hash table $cnt$ to count the number of times each integer in the array $arr$ appears, and then sort the values in $cnt$ in ascending order, and record them in the array $nums$. diff --git a/solution/1700-1799/1726.Tuple with Same Product/README_EN.md b/solution/1700-1799/1726.Tuple with Same Product/README_EN.md index 11323372983f5..91f1e29e20e5b 100644 --- a/solution/1700-1799/1726.Tuple with Same Product/README_EN.md +++ b/solution/1700-1799/1726.Tuple with Same Product/README_EN.md @@ -40,7 +40,7 @@ ## Solutions -**Approach 1: Number of Combinations + Hash Table** +**Solution 1: Number of Combinations + Hash Table** Time complexity $O(n^2)$, Space complexity $O(n^2)$. diff --git a/solution/1700-1799/1749.Maximum Absolute Sum of Any Subarray/README_EN.md b/solution/1700-1799/1749.Maximum Absolute Sum of Any Subarray/README_EN.md index f4ed248271c85..7f3b3e0659f2b 100644 --- a/solution/1700-1799/1749.Maximum Absolute Sum of Any Subarray/README_EN.md +++ b/solution/1700-1799/1749.Maximum Absolute Sum of Any Subarray/README_EN.md @@ -42,7 +42,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** We define $f[i]$ to represent the maximum value of the subarray ending with $nums[i]$, and define $g[i]$ to represent the minimum value of the subarray ending with $nums[i]$. Then the state transition equation of $f[i]$ and $g[i]$ is as follows: diff --git a/solution/1700-1799/1750.Minimum Length of String After Deleting Similar Ends/README_EN.md b/solution/1700-1799/1750.Minimum Length of String After Deleting Similar Ends/README_EN.md index 0ad0acf18ec2d..b5849d808aacf 100644 --- a/solution/1700-1799/1750.Minimum Length of String After Deleting Similar Ends/README_EN.md +++ b/solution/1700-1799/1750.Minimum Length of String After Deleting Similar Ends/README_EN.md @@ -56,7 +56,7 @@ ## Solutions -**Approach 1: Two pointers** +**Solution 1: Two pointers** We define two pointers $i$ and $j$ to point to the head and tail of the string $s$ respectively, then move them to the middle until the characters pointed to by $i$ and $j$ are not equal, then $\max(0, j - i + 1)$ is the answer. diff --git a/solution/2000-2099/2068.Check Whether Two Strings are Almost Equivalent/README_EN.md b/solution/2000-2099/2068.Check Whether Two Strings are Almost Equivalent/README_EN.md index 484191251af4d..639522ded8451 100644 --- a/solution/2000-2099/2068.Check Whether Two Strings are Almost Equivalent/README_EN.md +++ b/solution/2000-2099/2068.Check Whether Two Strings are Almost Equivalent/README_EN.md @@ -57,7 +57,7 @@ The difference is 4, which is more than the allowed 3. ## Solutions -**Approach 1: Counting** +**Solution 1: Counting** We can create an array $cnt$ of length $26$ to record the difference in the number of times each letter appears in the two strings. Then we traverse $cnt$, if any letter appears the difference in the number of times greater than $3$, then return `false`, otherwise return `true`. diff --git a/solution/2400-2499/2418.Sort the People/README.md b/solution/2400-2499/2418.Sort the People/README.md index 427d94a16291c..61b02da62003a 100644 --- a/solution/2400-2499/2418.Sort the People/README.md +++ b/solution/2400-2499/2418.Sort the People/README.md @@ -223,6 +223,28 @@ impl Solution { } ``` +### **PHP** + +```php +class Solution { + /** + * @param String[] $names + * @param Integer[] $heights + * @return String[] + */ + function sortPeople($names, $heights) { + for ($i = 0; $i < count($heights); $i++) { + $hashtable[$heights[$i]] = $names[$i]; + } + rsort($heights); + for ($j = 0; $j < count($heights); $j++) { + $rs[$j] = $hashtable[$heights[$j]]; + } + return $rs; + } +} +``` + ### **...** ``` diff --git a/solution/2400-2499/2418.Sort the People/README_EN.md b/solution/2400-2499/2418.Sort the People/README_EN.md index 4a6b0e7e1e2f6..feaf4722bb1ce 100644 --- a/solution/2400-2499/2418.Sort the People/README_EN.md +++ b/solution/2400-2499/2418.Sort the People/README_EN.md @@ -207,6 +207,28 @@ impl Solution { } ``` +### **PHP** + +```php +class Solution { + /** + * @param String[] $names + * @param Integer[] $heights + * @return String[] + */ + function sortPeople($names, $heights) { + for ($i = 0; $i < count($heights); $i++) { + $hashtable[$heights[$i]] = $names[$i]; + } + rsort($heights); + for ($j = 0; $j < count($heights); $j++) { + $rs[$j] = $hashtable[$heights[$j]]; + } + return $rs; + } +} +``` + ### **...** ``` diff --git a/solution/2400-2499/2418.Sort the People/Solution.php b/solution/2400-2499/2418.Sort the People/Solution.php new file mode 100644 index 0000000000000..d3f19a0b54fc4 --- /dev/null +++ b/solution/2400-2499/2418.Sort the People/Solution.php @@ -0,0 +1,17 @@ +class Solution { + /** + * @param String[] $names + * @param Integer[] $heights + * @return String[] + */ + function sortPeople($names, $heights) { + for ($i = 0; $i < count($heights); $i++) { + $hashtable[$heights[$i]] = $names[$i]; + } + rsort($heights); + for ($j = 0; $j < count($heights); $j++) { + $rs[$j] = $hashtable[$heights[$j]]; + } + return $rs; + } +} \ No newline at end of file diff --git a/solution/2500-2599/2578.Split With Minimum Sum/README_EN.md b/solution/2500-2599/2578.Split With Minimum Sum/README_EN.md index ad64d218ab34a..681f070c78c31 100644 --- a/solution/2500-2599/2578.Split With Minimum Sum/README_EN.md +++ b/solution/2500-2599/2578.Split With Minimum Sum/README_EN.md @@ -50,7 +50,7 @@ ## Solutions -**Approach 1: Count + Greedy** +**Solution 1: Count + Greedy** We first use a hash table or array `cnt` to count the number of times each digit appears in `num`, and use the variable `n` to record the number of digits in `num`. @@ -58,7 +58,7 @@ Then, enumerate the number of digits $i$ of `nums`, and assign the numbers in `c The time complexity is $O(n)$ and the space complexity is $O(C)$. Where $n$ is the number of digits in `num`; and $C$ is the number of different numbers in `num`, which is $C \leq 10$ in this problem. -**Approach 2: Sorting + Greedy** +**Solution 2: Sorting + Greedy** We can convert `num` to a string or character array and sort it. Then assign the numbers in the sorted array in ascending order alternately to `num1` and `num2`, and finally return the sum of `num1` and `num2`. diff --git a/solution/2500-2599/2579.Count Total Number of Colored Cells/README_EN.md b/solution/2500-2599/2579.Count Total Number of Colored Cells/README_EN.md index 89b4925c77011..0c67279787cad 100644 --- a/solution/2500-2599/2579.Count Total Number of Colored Cells/README_EN.md +++ b/solution/2500-2599/2579.Count Total Number of Colored Cells/README_EN.md @@ -41,7 +41,7 @@ ## Solutions -**Approach 1: Mathematics** +**Solution 1: Mathematics** We find that after the $n$th minute, there are a total of $2 \times n - 1$ columns in the grid, and the numbers on each column are respectively $1, 3, 5, \cdots, 2 \times n - 1, 2 \times n - 3, \cdots, 3, 1$. The left and right parts are both arithmetic progressions, and the sum can be obtained by $2 \times n \times (n - 1) + 1$. diff --git a/solution/2500-2599/2581.Count Number of Possible Root Nodes/README_EN.md b/solution/2500-2599/2581.Count Number of Possible Root Nodes/README_EN.md index 48f7b03e17b86..26645ee06f814 100644 --- a/solution/2500-2599/2581.Count Number of Possible Root Nodes/README_EN.md +++ b/solution/2500-2599/2581.Count Number of Possible Root Nodes/README_EN.md @@ -72,7 +72,7 @@ Considering any node as root will give at least 1 correct guess. ## Solutions -**Approach 1: Tree DP (change root)** +**Solution 1: Tree DP (change root)** First, we traverse the given edge set $edges$ and convert it to an adjacency list $g$ where $g[i]$ represents the adjacent nodes of node $i$. Use a hash map $gs$ to record the given guess set $guesses$. diff --git a/solution/2500-2599/2582.Pass the Pillow/README_EN.md b/solution/2500-2599/2582.Pass the Pillow/README_EN.md index d32b021b2acb8..c3912cbb33256 100644 --- a/solution/2500-2599/2582.Pass the Pillow/README_EN.md +++ b/solution/2500-2599/2582.Pass the Pillow/README_EN.md @@ -40,13 +40,13 @@ Afer two seconds, the pillow is given to the 3rd person. ## Solutions -**Approach 1: Simulation** +**Solution 1: Simulation** We can simulate the process of passing the pillow, and each time the pillow is passed, if the pillow reaches the front or the end of the queue, the direction of the pillow will change, and the queue will continue to pass the pillow along the opposite direction. The time complexity is $O(time)$ and the space complexity is $O(1)$, where $time$ is the given time. -**Approach 2: Math** +**Solution 2: Math** We notice that there are $n - 1$ passes in each round. Therefore, we can divide $time$ by $n - 1$ to get the number of rounds $k$ that the pillow is passed, and then take the remainder of $time$ modulo $n - 1$ to get the remaining passes $mod$ in the current round. diff --git a/solution/2500-2599/2585.Number of Ways to Earn Points/README_EN.md b/solution/2500-2599/2585.Number of Ways to Earn Points/README_EN.md index 813a3ebfb90a3..19eaa5d93781f 100644 --- a/solution/2500-2599/2585.Number of Ways to Earn Points/README_EN.md +++ b/solution/2500-2599/2585.Number of Ways to Earn Points/README_EN.md @@ -66,7 +66,7 @@ ## Solutions -**Approach 1: Dynamic Programming** +**Solution 1: Dynamic Programming** We define $f[i][j]$ to represent the number of methods to get $j$ points exactly from the first $i$ types of questions. Initially, $f[0][0] = 1$, and the rest $f[i][j] = 0$. The answer is $f[n][target]$. diff --git a/solution/2500-2599/2586.Count the Number of Vowel Strings in Range/README_EN.md b/solution/2500-2599/2586.Count the Number of Vowel Strings in Range/README_EN.md index 6abadd7087d2a..6b9463bbc104a 100644 --- a/solution/2500-2599/2586.Count the Number of Vowel Strings in Range/README_EN.md +++ b/solution/2500-2599/2586.Count the Number of Vowel Strings in Range/README_EN.md @@ -48,7 +48,7 @@ The number of vowel strings in the mentioned range is 3. ## Solutions -**Approach 1: Simulation** +**Solution 1: Simulation** We just need to traverse the string in the interval $[left,.. right]$, and check if it starts and ends with a vowel. If so, the answer plus one. diff --git a/solution/2500-2599/2588.Count the Number of Beautiful Subarrays/README_EN.md b/solution/2500-2599/2588.Count the Number of Beautiful Subarrays/README_EN.md index c186e23d61624..e03b7e4f220ad 100644 --- a/solution/2500-2599/2588.Count the Number of Beautiful Subarrays/README_EN.md +++ b/solution/2500-2599/2588.Count the Number of Beautiful Subarrays/README_EN.md @@ -52,7 +52,7 @@ ## Solutions -**Approach 1: Prefix XOR + Hash Table** +**Solution 1: Prefix XOR + Hash Table** We observe that a subarray can become an array of all $0$ s if and only if the number of $1$s in each bit of all the elements in the subarray is even. diff --git a/solution/2500-2599/2589.Minimum Time to Complete All Tasks/README_EN.md b/solution/2500-2599/2589.Minimum Time to Complete All Tasks/README_EN.md index 2c23d5106d20f..7b4bf9dafe267 100644 --- a/solution/2500-2599/2589.Minimum Time to Complete All Tasks/README_EN.md +++ b/solution/2500-2599/2589.Minimum Time to Complete All Tasks/README_EN.md @@ -47,7 +47,7 @@ The computer will be on for a total of 4 seconds. ## Solutions -**Approach 1: Greedy + Sort** +**Solution 1: Greedy + Sort** We find that the problem is equivalent to choosing $duration$ integer time points in each interval $[start,..,end]$ so that the total number of integer time points selected is the smallest. diff --git a/solution/2500-2599/2590.Design a Todo List/README_EN.md b/solution/2500-2599/2590.Design a Todo List/README_EN.md index db8bcb5cfc378..ce87b0528c698 100644 --- a/solution/2500-2599/2590.Design a Todo List/README_EN.md +++ b/solution/2500-2599/2590.Design a Todo List/README_EN.md @@ -57,7 +57,7 @@ todoList.getAllTasks(1); // return ["Task3", "Task1"]. User ## Solutions -**Approach 1: Hash Table + Sorted Set** +**Solution 1: Hash Table + Sorted Set** We use a hash table $tasks$ to record the set of tasks for each user, where the key is the user ID and the value is a sorted set sorted by the deadline of the task. In addition, we use a variable $i$ to record the current task ID. diff --git a/solution/2500-2599/2591.Distribute Money to Maximum Children/README_EN.md b/solution/2500-2599/2591.Distribute Money to Maximum Children/README_EN.md index 5369db385332c..25a6ecd34efa8 100644 --- a/solution/2500-2599/2591.Distribute Money to Maximum Children/README_EN.md +++ b/solution/2500-2599/2591.Distribute Money to Maximum Children/README_EN.md @@ -48,7 +48,7 @@ It can be proven that no distribution exists such that number of children gettin ## Solutions -**Approach 1: Case analysis** +**Solution 1: Case analysis** If $money \lt children$, then there must be a child who did not receive money, return $-1$. diff --git a/solution/2500-2599/2592.Maximize Greatness of an Array/README_EN.md b/solution/2500-2599/2592.Maximize Greatness of an Array/README_EN.md index 6aa53327a4cb1..07cea0d812745 100644 --- a/solution/2500-2599/2592.Maximize Greatness of an Array/README_EN.md +++ b/solution/2500-2599/2592.Maximize Greatness of an Array/README_EN.md @@ -38,7 +38,7 @@ At indices = 0, 1, and 2, perm[i] > nums[i]. Hence, we return 3. ## Solutions -**Approach 1: Greedy** +**Solution 1: Greedy** We can sort the array $nums$ first. diff --git a/solution/2500-2599/2593.Find Score of an Array After Marking All Elements/README_EN.md b/solution/2500-2599/2593.Find Score of an Array After Marking All Elements/README_EN.md index 8ce1189c41e73..6ae8f7876a4eb 100644 --- a/solution/2500-2599/2593.Find Score of an Array After Marking All Elements/README_EN.md +++ b/solution/2500-2599/2593.Find Score of an Array After Marking All Elements/README_EN.md @@ -52,7 +52,7 @@ Our score is 1 + 2 + 2 = 5. ## Solutions -**Approach 1: Priority Queue (Min Heap)** +**Solution 1: Priority Queue (Min Heap)** We use a priority queue to maintain the unmarked elements in the array, and each item in the queue is a tuple $(x, i)$, where $x$ and $i$ represent the element value and index of the array respectively. An array $vis$ is used to record whether the element in the array is marked. @@ -62,7 +62,7 @@ Finally, return the answer. The time complexity is $O(n \times \log n)$ and the space complexity is $O(n)$, where $n$ is the length of the array. -**Approach 2: Sorting** +**Solution 2: Sorting** We can create an index array $idx$ where $idx[i]=i$, and then we sort the index array $idx$ according to the element values in the array $nums$. If the element values are the same, then sort them according to the index values. diff --git a/solution/2500-2599/2594.Minimum Time to Repair Cars/README_EN.md b/solution/2500-2599/2594.Minimum Time to Repair Cars/README_EN.md index 58c11c5fb9bd7..4c09bcf3d5de1 100644 --- a/solution/2500-2599/2594.Minimum Time to Repair Cars/README_EN.md +++ b/solution/2500-2599/2594.Minimum Time to Repair Cars/README_EN.md @@ -49,7 +49,7 @@ It can be proved that the cars cannot be repaired in less than 16 minutes.​​ ## Solutions -**Approach 1: Binary Search** +**Solution 1: Binary Search** We notice that the longer the repair time, the more repaired cars. Therefore, we can use binary search to find the minimum repair time. diff --git a/solution/2500-2599/2595.Number of Even and Odd Bits/README_EN.md b/solution/2500-2599/2595.Number of Even and Odd Bits/README_EN.md index 324914cded323..957c4ebb86e8d 100644 --- a/solution/2500-2599/2595.Number of Even and Odd Bits/README_EN.md +++ b/solution/2500-2599/2595.Number of Even and Odd Bits/README_EN.md @@ -42,7 +42,7 @@ There are 0 even and 1 odd indices. ## Solutions -**Approach 1: Enumerate** +**Solution 1: Enumerate** According to the problem description, enumerate the binary representation of $n$ from the low bit to the high bit. If the bit is $1$, add $1$ to the corresponding counter according to whether the index of the bit is odd or even. diff --git a/solution/2500-2599/2596.Check Knight Tour Configuration/README_EN.md b/solution/2500-2599/2596.Check Knight Tour Configuration/README_EN.md index 1bb7c74217892..76f5f5f9ef073 100644 --- a/solution/2500-2599/2596.Check Knight Tour Configuration/README_EN.md +++ b/solution/2500-2599/2596.Check Knight Tour Configuration/README_EN.md @@ -41,7 +41,7 @@ ## Solutions -**Approach 1: Simulation** +**Solution 1: Simulation** We first use the array $pos$ to record the coordinates of the grid visited by the knight, and then traverse the $pos$ array to check whether the difference between the adjacent two grid coordinates is $(1, 2)$ or $(2, 1)$. If not, return `false`. diff --git a/solution/2500-2599/2597.The Number of Beautiful Subsets/README_EN.md b/solution/2500-2599/2597.The Number of Beautiful Subsets/README_EN.md index c16a351fed1c3..07f33dd711063 100644 --- a/solution/2500-2599/2597.The Number of Beautiful Subsets/README_EN.md +++ b/solution/2500-2599/2597.The Number of Beautiful Subsets/README_EN.md @@ -41,7 +41,7 @@ It can be proved that there is only 1 beautiful subset in the array [1]. ## Solutions -**Approach 1: Counting + Backtracking** +**Solution 1: Counting + Backtracking** We use a hash table or an array $cnt$ to record the currently selected numbers and their counts, and use $ans$ to record the number of beautiful subsets, initially $ans = -1$, indicating that the empty set is excluded. diff --git a/solution/2500-2599/2598.Smallest Missing Non-negative Integer After Operations/README_EN.md b/solution/2500-2599/2598.Smallest Missing Non-negative Integer After Operations/README_EN.md index f442639e6269d..10a88deccc536 100644 --- a/solution/2500-2599/2598.Smallest Missing Non-negative Integer After Operations/README_EN.md +++ b/solution/2500-2599/2598.Smallest Missing Non-negative Integer After Operations/README_EN.md @@ -53,7 +53,7 @@ The MEX of nums is 2. It can be shown that 2 is the maximum MEX we can achieve. ## Solutions -**Approach 1: Count** +**Solution 1: Count** We use a hash table or array $cnt$ to count the number of times each remainder of $value$ is taken modulo in the array. diff --git a/solution/2600-2699/2601.Prime Subtraction Operation/README_EN.md b/solution/2600-2699/2601.Prime Subtraction Operation/README_EN.md index a998518c6e29b..741ea0c57a880 100644 --- a/solution/2600-2699/2601.Prime Subtraction Operation/README_EN.md +++ b/solution/2600-2699/2601.Prime Subtraction Operation/README_EN.md @@ -51,7 +51,7 @@ After the second operation, nums is sorted in strictly increasing order, so the ## Solutions -**Approach 1: Preprocessing prime numbers + binary search** +**Solution 1: Preprocessing prime numbers + binary search** We first preprocess all the primes within $1000$ and record them in the array $p$. diff --git a/solution/2600-2699/2602.Minimum Operations to Make All Array Elements Equal/README_EN.md b/solution/2600-2699/2602.Minimum Operations to Make All Array Elements Equal/README_EN.md index a21938f9dfb60..306bbd7e2ad9c 100644 --- a/solution/2600-2699/2602.Minimum Operations to Make All Array Elements Equal/README_EN.md +++ b/solution/2600-2699/2602.Minimum Operations to Make All Array Elements Equal/README_EN.md @@ -55,7 +55,7 @@ So the total number of operations for the second query is 2 + 4 + 1 + 3 = 10. ## Solutions -**Approach 1: sort + prefix sum + binary search** +**Solution 1: sort + prefix sum + binary search** First, we sort the array $nums$ and calculate the prefix sum array $s$ with a length of $n+1$, where $s[i]$ represents the sum of the first $i$ elements in the array $nums$. diff --git a/solution/2600-2699/2603.Collect Coins in a Tree/README_EN.md b/solution/2600-2699/2603.Collect Coins in a Tree/README_EN.md index 8f1a2dd5a350c..caddc56bb8852 100644 --- a/solution/2600-2699/2603.Collect Coins in a Tree/README_EN.md +++ b/solution/2600-2699/2603.Collect Coins in a Tree/README_EN.md @@ -50,7 +50,7 @@ ## Solutions -**Approach 1: Topological sorting** +**Solution 1: Topological sorting** We first convert the edges in $edges$ to the adjacency list $g$, where $g[i]$ represents all the adjacent nodes of node $i$, represented by a set. diff --git a/solution/2600-2699/2604.Minimum Time to Eat All Grains/README_EN.md b/solution/2600-2699/2604.Minimum Time to Eat All Grains/README_EN.md index 28d8c752741fa..f8717aa6353d5 100644 --- a/solution/2600-2699/2604.Minimum Time to Eat All Grains/README_EN.md +++ b/solution/2600-2699/2604.Minimum Time to Eat All Grains/README_EN.md @@ -50,7 +50,7 @@ So, the maximum time needed is 1. ## Solutions -**Approach 1: Sorting + Binary Search** +**Solution 1: Sorting + Binary Search** First, sort the chickens and grains by their position from left to right. Then enumerate the time $t$ using binary search to find the smallest $t$ such that all the grains can be eaten up in $t$ seconds. diff --git a/solution/2600-2699/2605.Form Smallest Number From Two Digit Arrays/README_EN.md b/solution/2600-2699/2605.Form Smallest Number From Two Digit Arrays/README_EN.md index 5e0095cc1a0e9..63cdfb32fb2b2 100644 --- a/solution/2600-2699/2605.Form Smallest Number From Two Digit Arrays/README_EN.md +++ b/solution/2600-2699/2605.Form Smallest Number From Two Digit Arrays/README_EN.md @@ -34,19 +34,19 @@ Given two arrays of unique digits nums1 and ## Solutions -**Approach 1: Enumeration** +**Solution 1: Enumeration** We observe that if there are the same numbers in the arrays $nums1$ and $nums2$, then the minimum of the same numbers is the smallest number. Otherwise, we take the number $a$ in the array $nums1$ and the number $b$ in the array $nums2$, and concatenate the two numbers $a$ and $b$ into two numbers, and take the smaller number. The time complexity is $O(m \times n)$, and the space complexity is $O(1)$, where $m$ and $n$ are the lengths of the arrays $nums1$ and $nums2$. -**Approach 2: Hash Table or Array + Enumeration** +**Solution 2: Hash Table or Array + Enumeration** We can use a hash table or array to record the numbers in the arrays $nums1$ and $nums2$, and then enumerate $1 \sim 9$. If $i$ appears in both arrays, then $i$ is the smallest number. Otherwise, we take the number $a$ in the array $nums1$ and the number $b$ in the array $nums2$, and concatenate the two numbers $a$ and $b$ into two numbers, and take the smaller number. The time complexity is $(m + n)$, and the space complexity is $O(C)$. Where $m$ and $n$ are the lengths of the arrays $nums1$ and $nums2$ respectively; and $C$ is the range of the numbers in the arrays $nums1$ and $nums2$, and the range in this problem is $C = 10$. -**Approach 3: Bit Operation** +**Solution 3: Bit Operation** Since the range of the numbers is $1 \sim 9$, we can use a binary number with a length of $10$ to represent the numbers in the arrays $nums1$ and $nums2$. We use $mask1$ to represent the numbers in the array $nums1$, and use $mask2$ to represent the numbers in the array $nums2$. diff --git a/solution/2600-2699/2606.Find the Substring With Maximum Cost/README_EN.md b/solution/2600-2699/2606.Find the Substring With Maximum Cost/README_EN.md index a5690a39a68c3..1f246ade55518 100644 --- a/solution/2600-2699/2606.Find the Substring With Maximum Cost/README_EN.md +++ b/solution/2600-2699/2606.Find the Substring With Maximum Cost/README_EN.md @@ -56,7 +56,7 @@ It can be proven that 0 is the maximum cost. ## Solutions -**Approach 1: Prefix sum + Maintain the minimum prefix sum** +**Solution 1: Prefix sum + Maintain the minimum prefix sum** According to the description of the problem, we traverse each character $c$ in the string $s$, obtain its corresponding value $v$, and then update the current prefix sum $tot=tot+v$. Then, the cost of the maximum cost substring ending with $c$ is $tot$ minus the minimum prefix sum $mi$, that is, $tot-mi$. We update the answer $ans=max(ans,tot-mi)$ and maintain the minimum prefix sum $mi=min(mi,tot)$. @@ -64,7 +64,7 @@ After the traversal is over, return the answer $ans$. The time complexity is $O(n)$, and the space complexity is $O(C)$. Where $n$ is the length of the string $s$; and $C$ is the size of the character set, which is $26$ in this problem. -**Approach 2: Convert to the maximum subarray sum problem** +**Solution 2: Convert to the maximum subarray sum problem** We can consider the value $v$ of each character $c$ as an integer, so the actual problem is to solve the maximum subarray sum problem. diff --git a/solution/2600-2699/2608.Shortest Cycle in a Graph/README_EN.md b/solution/2600-2699/2608.Shortest Cycle in a Graph/README_EN.md index 4bae15ba1a8d3..e8db26c38afdd 100644 --- a/solution/2600-2699/2608.Shortest Cycle in a Graph/README_EN.md +++ b/solution/2600-2699/2608.Shortest Cycle in a Graph/README_EN.md @@ -41,7 +41,7 @@ ## Solutions -**Approach 1: Enumerate edges + BFS** +**Solution 1: Enumerate edges + BFS** We first construct the adjacency list $g$ of the graph according to the array $edges$, where $g[u]$ represents all the adjacent vertices of vertex $u$. @@ -49,9 +49,9 @@ Then we enumerate the two-directional edge $(u, v)$, if the path from vertex $u$ The time complexity is $O(m^2)$ and the space complexity is $O(m + n)$, where $m$ and $n$ are the length of the array $edges$ and the number of vertices. -**Approach 2: Enumerate points + BFS** +**Solution 2: Enumerate points + BFS** -Similar to Approach 1, we first construct the adjacency list $g$ of the graph according to the array $edges$, where $g[u]$ represents all the adjacent vertices of vertex $u$. +Similar to Solution 1, we first construct the adjacency list $g$ of the graph according to the array $edges$, where $g[u]$ represents all the adjacent vertices of vertex $u$. Then we enumerate the vertex $u$, if there are two paths from vertex $u$ to vertex $v$, then we currently find a cycle, the length is the sum of the length of the two paths. We take the minimum of all these cycles. diff --git a/solution/2600-2699/2609.Find the Longest Balanced Substring of a Binary String/README_EN.md b/solution/2600-2699/2609.Find the Longest Balanced Substring of a Binary String/README_EN.md index 37c72d6516d0b..16aa8a9397d1a 100644 --- a/solution/2600-2699/2609.Find the Longest Balanced Substring of a Binary String/README_EN.md +++ b/solution/2600-2699/2609.Find the Longest Balanced Substring of a Binary String/README_EN.md @@ -47,13 +47,13 @@ ## Solutions -**Approach 1: Brute force** +**Solution 1: Brute force** Since the range of $n$ is small, we can enumerate all substrings $s[i..j]$ to check if it is a balanced string. If so, update the answer. The time complexity is $O(n^3)$, and the space complexity is $O(1)$. Where $n$ is the length of string $s$. -**Approach 2: Enumeration optimization** +**Solution 2: Enumeration optimization** We use variables $zero$ and $one$ to record the number of continuous $0$ and $1$. diff --git a/solution/2600-2699/2610.Convert an Array Into a 2D Array With Conditions/README_EN.md b/solution/2600-2699/2610.Convert an Array Into a 2D Array With Conditions/README_EN.md index 7fac4f5531182..e4750e02ed500 100644 --- a/solution/2600-2699/2610.Convert an Array Into a 2D Array With Conditions/README_EN.md +++ b/solution/2600-2699/2610.Convert an Array Into a 2D Array With Conditions/README_EN.md @@ -47,7 +47,7 @@ It can be shown that we cannot have less than 3 rows in a valid array. ## Solutions -**Approach 1: Array or Hash Table** +**Solution 1: Array or Hash Table** We use an array or hash table $cnt$ to count the number of occurrences of each element in the array $nums$. diff --git a/solution/2600-2699/2611.Mice and Cheese/README_EN.md b/solution/2600-2699/2611.Mice and Cheese/README_EN.md index c31de2c8ad6e7..9efa25d515057 100644 --- a/solution/2600-2699/2611.Mice and Cheese/README_EN.md +++ b/solution/2600-2699/2611.Mice and Cheese/README_EN.md @@ -49,7 +49,7 @@ It can be proven that 2 is the maximum total points that the mice can achieve. ## Solutions -**Approach 1: Greedy + Sort** +**Solution 1: Greedy + Sort** We can first give all the cheese to the second mouse. Next, consider giving $k$ pieces of cheese to the first mouse. How should we choose these $k$ pieces of cheese? Obviously, if we give the $i$-th piece of cheese from the second mouse to the first mouse, the change in the score is $reward1[i] - reward2[i]$. We hope that this change is as large as possible, so that the total score is maximized. diff --git a/solution/2600-2699/2612.Minimum Reverse Operations/README_EN.md b/solution/2600-2699/2612.Minimum Reverse Operations/README_EN.md index 1825efca6cb2b..5dbacdd51a102 100644 --- a/solution/2600-2699/2612.Minimum Reverse Operations/README_EN.md +++ b/solution/2600-2699/2612.Minimum Reverse Operations/README_EN.md @@ -58,7 +58,7 @@ ## Solutions -**Approach 1: Ordered Set + BFS** +**Solution 1: Ordered Set + BFS** We notice that for any index $i$ in the subarray interval $[l,..r]$, the flipped index $j = l + r - i$. diff --git a/solution/2600-2699/2613.Beautiful Pairs/README_EN.md b/solution/2600-2699/2613.Beautiful Pairs/README_EN.md index 7563998886a55..57dc4f0351876 100644 --- a/solution/2600-2699/2613.Beautiful Pairs/README_EN.md +++ b/solution/2600-2699/2613.Beautiful Pairs/README_EN.md @@ -44,7 +44,7 @@ ## Solutions -**Approach 1: Sorting + Divide and Conquer** +**Solution 1: Sorting + Divide and Conquer** This problem is equivalent to finding two points in the plane, such that the Manhattan distance between them is the smallest. If there are multiple points satisfying the condition, return the one with the smallest index. diff --git a/solution/2600-2699/2614.Prime In Diagonal/README_EN.md b/solution/2600-2699/2614.Prime In Diagonal/README_EN.md index bcb9a3930fb09..0266782ddd57b 100644 --- a/solution/2600-2699/2614.Prime In Diagonal/README_EN.md +++ b/solution/2600-2699/2614.Prime In Diagonal/README_EN.md @@ -47,7 +47,7 @@ ## Solutions -**Approach 1: Math + Simulation** +**Solution 1: Math + Simulation** We implement a function `is_prime` to check whether a number is prime. diff --git a/solution/2600-2699/2616.Minimize the Maximum Difference of Pairs/README_EN.md b/solution/2600-2699/2616.Minimize the Maximum Difference of Pairs/README_EN.md index d386bfc6b1142..8be51cde34b0b 100644 --- a/solution/2600-2699/2616.Minimize the Maximum Difference of Pairs/README_EN.md +++ b/solution/2600-2699/2616.Minimize the Maximum Difference of Pairs/README_EN.md @@ -39,7 +39,7 @@ The maximum difference is max(|nums[1] - nums[4]|, |nums[2] - nums[5]|) = max(0, ## Solutions -**Approach 1: Binary search + Greedy** +**Solution 1: Binary search + Greedy** We find that the maximum difference has the monotonicity, that is, if the maximum difference $x$ satisfies the condition, then $x-1$ must also satisfy the condition. Therefore, we can use the binary search method to find the smallest maximum difference that satisfies the condition. diff --git a/solution/2600-2699/2617.Minimum Number of Visited Cells in a Grid/README_EN.md b/solution/2600-2699/2617.Minimum Number of Visited Cells in a Grid/README_EN.md index da36e9af825c8..647c718ae4517 100644 --- a/solution/2600-2699/2617.Minimum Number of Visited Cells in a Grid/README_EN.md +++ b/solution/2600-2699/2617.Minimum Number of Visited Cells in a Grid/README_EN.md @@ -54,7 +54,7 @@ ## Solutions -**Approach 1: Priority Queue** +**Solution 1: Priority Queue** Let's denote the number of rows of the grid as $m$ and the number of columns as $n$. Define $dist[i][j]$ to be the shortest distance from the coordinate $(0, 0)$ to the coordinate $(i, j)$. Initially, $dist[0][0]=1$ and $dist[i][j]=-1$ for all other $i$ and $j$. diff --git a/solution/2600-2699/2634.Filter Elements from Array/README_EN.md b/solution/2600-2699/2634.Filter Elements from Array/README_EN.md index 37e09f5ea16c0..bc3254523a77c 100644 --- a/solution/2600-2699/2634.Filter Elements from Array/README_EN.md +++ b/solution/2600-2699/2634.Filter Elements from Array/README_EN.md @@ -49,7 +49,7 @@ Falsey values such as 0 should be filtered out ## Solutions -**Approach 1: Traversal** +**Solution 1: Traversal** We traverse the array $arr$ and for each element $arr[i]$, if $fn(arr[i], i)$ is true, we add it to the answer array. Finally, we return the answer array. diff --git a/solution/2600-2699/2635.Apply Transform Over Each Element in Array/README_EN.md b/solution/2600-2699/2635.Apply Transform Over Each Element in Array/README_EN.md index 15782c78572bf..fe772c82ab1e7 100644 --- a/solution/2600-2699/2635.Apply Transform Over Each Element in Array/README_EN.md +++ b/solution/2600-2699/2635.Apply Transform Over Each Element in Array/README_EN.md @@ -48,7 +48,7 @@ The function increases each value in the array by one. ## Solutions -**Approach 1: traversal** +**Solution 1: traversal** We traverse the array $arr$, for each element $arr[i]$, replace it with $fn(arr[i], i)$. Finally, return the array $arr$. diff --git a/solution/2600-2699/2638.Count the Number of K-Free Subsets/README_EN.md b/solution/2600-2699/2638.Count the Number of K-Free Subsets/README_EN.md index 27ab4963d0346..e44b908d4eff2 100644 --- a/solution/2600-2699/2638.Count the Number of K-Free Subsets/README_EN.md +++ b/solution/2600-2699/2638.Count the Number of K-Free Subsets/README_EN.md @@ -48,7 +48,7 @@ ## Solutions -**Approach 1: Grouping + Dynamic Programming** +**Solution 1: Grouping + Dynamic Programming** First, sort the array $nums$ in ascending order, and then group the elements in the array according to the remainder modulo $k$, that is, the elements $nums[i] \bmod k$ with the same remainder are in the same group. Then for any two elements in different groups, their absolute difference is not equal to $k$. Therefore, we can obtain the number of subsets in each group, and then multiply the number of subsets in each group to obtain the answer. diff --git a/solution/2600-2699/2647.Color the Triangle Red/README_EN.md b/solution/2600-2699/2647.Color the Triangle Red/README_EN.md index 921edbe688f73..dc4a9ec4aae66 100644 --- a/solution/2600-2699/2647.Color the Triangle Red/README_EN.md +++ b/solution/2600-2699/2647.Color the Triangle Red/README_EN.md @@ -65,7 +65,7 @@ It can be shown that choosing any 2 triangles and running the algorithm will not ## Solutions -**Approach 1: Find the Pattern** +**Solution 1: Find the Pattern** We draw a graph to observe, and we can find that the first row only has one triangle and must be colored, and from the last row to the second row, the coloring scheme of every four rows is the same: diff --git a/solution/2600-2699/2647.Color the Triangle Red/images/demo2.png b/solution/2600-2699/2647.Color the Triangle Red/images/demo2.png index 642f0c4e401e3..b813d00162f1f 100644 Binary files a/solution/2600-2699/2647.Color the Triangle Red/images/demo2.png and b/solution/2600-2699/2647.Color the Triangle Red/images/demo2.png differ diff --git a/solution/2600-2699/2647.Color the Triangle Red/images/demo3.png b/solution/2600-2699/2647.Color the Triangle Red/images/demo3.png index d728b510c3d17..8d36d700475de 100644 Binary files a/solution/2600-2699/2647.Color the Triangle Red/images/demo3.png and b/solution/2600-2699/2647.Color the Triangle Red/images/demo3.png differ diff --git a/solution/2600-2699/2647.Color the Triangle Red/images/example1.jpg b/solution/2600-2699/2647.Color the Triangle Red/images/example1.jpg index 30fbd0d7b81d6..6cdd8d8d4228e 100644 Binary files a/solution/2600-2699/2647.Color the Triangle Red/images/example1.jpg and b/solution/2600-2699/2647.Color the Triangle Red/images/example1.jpg differ diff --git a/solution/2600-2699/2647.Color the Triangle Red/images/example2.jpg b/solution/2600-2699/2647.Color the Triangle Red/images/example2.jpg index c9e737929141b..03ae6ca029057 100644 Binary files a/solution/2600-2699/2647.Color the Triangle Red/images/example2.jpg and b/solution/2600-2699/2647.Color the Triangle Red/images/example2.jpg differ diff --git a/solution/2600-2699/2647.Color the Triangle Red/images/triangle4.jpg b/solution/2600-2699/2647.Color the Triangle Red/images/triangle4.jpg index ac98c976de033..2e31ae833251e 100644 Binary files a/solution/2600-2699/2647.Color the Triangle Red/images/triangle4.jpg and b/solution/2600-2699/2647.Color the Triangle Red/images/triangle4.jpg differ