From 3550db3ddbbd978299f4f7e51f600af730bbb9ec Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Wed, 5 Feb 2025 19:33:27 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.1946 (#4028) No.1946.Largest Number After Mutating Substring --- .../README.md | 126 +++++++++++++++--- .../README_EN.md | 126 +++++++++++++++--- .../Solution.cpp | 13 +- .../Solution.go | 13 +- .../Solution.java | 15 ++- .../Solution.js | 20 +++ .../Solution.py | 12 +- .../Solution.rs | 17 +++ .../Solution.ts | 15 +++ 9 files changed, 296 insertions(+), 61 deletions(-) create mode 100644 solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.js create mode 100644 solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.rs create mode 100644 solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.ts diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/README.md b/solution/1900-1999/1946.Largest Number After Mutating Substring/README.md index 864a97785e26f..67cb4a2bab373 100644 --- a/solution/1900-1999/1946.Largest Number After Mutating Substring/README.md +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/README.md @@ -49,7 +49,7 @@ tags: - 2 映射为 change[2] = 3 。 - 1 映射为 change[1] = 4 。 因此,"021" 变为 "934" 。 -"934" 是可以构造的最大整数,所以返回它的字符串表示。 +"934" 是可以构造的最大整数,所以返回它的字符串表示。

示例 3:

@@ -78,9 +78,15 @@ tags: ### 方法一:贪心 -从左到右遍历字符串 `num`,找到第一个比 `change` 中对应数字小的数字,然后将其替换为 `change` 中对应的数字,直到遇到比 `change` 中对应数字大的数字,停止替换。 +根据题目描述,我们可以从字符串的高位开始,贪心的进行连续的替换操作,直到遇到一个比当前位数字小的数字为止。 -时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 `num` 的长度。 +我们先将字符串 $\textit{num}$ 转换为字符数组 $\textit{s}$,用一个变量 $\textit{changed}$ 记录是否已经发生过变化,初始时 $\textit{changed} = \text{false}$。 + +然后我们遍历字符数组 $\textit{s}$,对于每个字符 $\textit{c}$,我们将其转换为数字 $\textit{d} = \text{change}[\text{int}(\textit{c})]$,如果已经发生过变化且 $\textit{d} < \textit{c}$,则说明我们不能再继续变化,直接退出循环;否则,如果 $\textit{d} > \textit{c}$,则说明我们可以将 $\textit{c}$ 替换为 $\textit{d}$,此时我们将 $\textit{changed} = \text{true}$,并将 $\textit{s}[i]$ 替换为 $\textit{d}$。 + +最后我们将字符数组 $\textit{s}$ 转换为字符串并返回即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $\textit{num}$ 的长度。 @@ -90,13 +96,15 @@ tags: class Solution: def maximumNumber(self, num: str, change: List[int]) -> str: s = list(num) + changed = False for i, c in enumerate(s): - if change[int(c)] > int(c): - while i < len(s) and int(s[i]) <= change[int(s[i])]: - s[i] = str(change[int(s[i])]) - i += 1 + d = str(change[int(c)]) + if changed and d < c: break - return ''.join(s) + if d > c: + changed = True + s[i] = d + return "".join(s) ``` #### Java @@ -105,15 +113,18 @@ class Solution: class Solution { public String maximumNumber(String num, int[] change) { char[] s = num.toCharArray(); + boolean changed = false; for (int i = 0; i < s.length; ++i) { - if (change[s[i] - '0'] > s[i] - '0') { - for (; i < s.length && s[i] - '0' <= change[s[i] - '0']; ++i) { - s[i] = (char) (change[s[i] - '0'] + '0'); - } + char d = (char) (change[s[i] - '0'] + '0'); + if (changed && d < s[i]) { break; } + if (d > s[i]) { + changed = true; + s[i] = d; + } } - return String.valueOf(s); + return new String(s); } } ``` @@ -125,13 +136,16 @@ class Solution { public: string maximumNumber(string num, vector& change) { int n = num.size(); + bool changed = false; for (int i = 0; i < n; ++i) { - if (change[num[i] - '0'] > num[i] - '0') { - for (; i < n && change[num[i] - '0'] >= num[i] - '0'; ++i) { - num[i] = change[num[i] - '0'] + '0'; - } + char d = '0' + change[num[i] - '0']; + if (changed && d < num[i]) { break; } + if (d > num[i]) { + changed = true; + num[i] = d; + } } return num; } @@ -143,18 +157,88 @@ public: ```go func maximumNumber(num string, change []int) string { s := []byte(num) + changed := false for i, c := range num { - if change[c-'0'] > int(c-'0') { - for ; i < len(s) && change[s[i]-'0'] >= int(s[i]-'0'); i++ { - s[i] = byte(change[s[i]-'0']) + '0' - } + d := byte('0' + change[c-'0']) + if changed && d < s[i] { break } + if d > s[i] { + s[i] = d + changed = true + } } return string(s) } ``` +#### TypeScript + +```ts +function maximumNumber(num: string, change: number[]): string { + const s = num.split(''); + let changed = false; + for (let i = 0; i < s.length; ++i) { + const d = change[+s[i]].toString(); + if (changed && d < s[i]) { + break; + } + if (d > s[i]) { + s[i] = d; + changed = true; + } + } + return s.join(''); +} +``` + +#### Rust + +```rust +impl Solution { + pub fn maximum_number(num: String, change: Vec) -> String { + let mut s: Vec = num.chars().collect(); + let mut changed = false; + for i in 0..s.len() { + let d = (change[s[i] as usize - '0' as usize] + '0' as i32) as u8 as char; + if changed && d < s[i] { + break; + } + if d > s[i] { + changed = true; + s[i] = d; + } + } + s.into_iter().collect() + } +} +``` + +#### JavaScript + +```js +/** + * @param {string} num + * @param {number[]} change + * @return {string} + */ +var maximumNumber = function (num, change) { + const s = num.split(''); + let changed = false; + for (let i = 0; i < s.length; ++i) { + const d = change[+s[i]].toString(); + if (changed && d < s[i]) { + break; + } + if (d > s[i]) { + s[i] = d; + changed = true; + } + } + return s.join(''); +}; +``` + diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/README_EN.md b/solution/1900-1999/1946.Largest Number After Mutating Substring/README_EN.md index bb56bffe2c0c1..78087c41b85b0 100644 --- a/solution/1900-1999/1946.Largest Number After Mutating Substring/README_EN.md +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/README_EN.md @@ -77,7 +77,17 @@ Thus, "021" becomes "934". -### Solution 1 +### Solution 1: Greedy + +According to the problem description, we can start from the highest digit of the string and greedily perform continuous replacement operations until we encounter a digit smaller than the current digit. + +First, we convert the string $\textit{num}$ into a character array $\textit{s}$ and use a variable $\textit{changed}$ to record whether a change has already occurred, initially $\textit{changed} = \text{false}$. + +Then we traverse the character array $\textit{s}$. For each character $\textit{c}$, we convert it to a number $\textit{d} = \text{change}[\text{int}(\textit{c})]$. If a change has already occurred and $\textit{d} < \textit{c}$, it means we cannot continue changing, so we exit the loop immediately. Otherwise, if $\textit{d} > \textit{c}$, it means we can replace $\textit{c}$ with $\textit{d}$. At this point, we set $\textit{changed} = \text{true}$ and replace $\textit{s}[i]$ with $\textit{d}$. + +Finally, we convert the character array $\textit{s}$ back to a string and return it. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $\textit{num}$. @@ -87,13 +97,15 @@ Thus, "021" becomes "934". class Solution: def maximumNumber(self, num: str, change: List[int]) -> str: s = list(num) + changed = False for i, c in enumerate(s): - if change[int(c)] > int(c): - while i < len(s) and int(s[i]) <= change[int(s[i])]: - s[i] = str(change[int(s[i])]) - i += 1 + d = str(change[int(c)]) + if changed and d < c: break - return ''.join(s) + if d > c: + changed = True + s[i] = d + return "".join(s) ``` #### Java @@ -102,15 +114,18 @@ class Solution: class Solution { public String maximumNumber(String num, int[] change) { char[] s = num.toCharArray(); + boolean changed = false; for (int i = 0; i < s.length; ++i) { - if (change[s[i] - '0'] > s[i] - '0') { - for (; i < s.length && s[i] - '0' <= change[s[i] - '0']; ++i) { - s[i] = (char) (change[s[i] - '0'] + '0'); - } + char d = (char) (change[s[i] - '0'] + '0'); + if (changed && d < s[i]) { break; } + if (d > s[i]) { + changed = true; + s[i] = d; + } } - return String.valueOf(s); + return new String(s); } } ``` @@ -122,13 +137,16 @@ class Solution { public: string maximumNumber(string num, vector& change) { int n = num.size(); + bool changed = false; for (int i = 0; i < n; ++i) { - if (change[num[i] - '0'] > num[i] - '0') { - for (; i < n && change[num[i] - '0'] >= num[i] - '0'; ++i) { - num[i] = change[num[i] - '0'] + '0'; - } + char d = '0' + change[num[i] - '0']; + if (changed && d < num[i]) { break; } + if (d > num[i]) { + changed = true; + num[i] = d; + } } return num; } @@ -140,18 +158,88 @@ public: ```go func maximumNumber(num string, change []int) string { s := []byte(num) + changed := false for i, c := range num { - if change[c-'0'] > int(c-'0') { - for ; i < len(s) && change[s[i]-'0'] >= int(s[i]-'0'); i++ { - s[i] = byte(change[s[i]-'0']) + '0' - } + d := byte('0' + change[c-'0']) + if changed && d < s[i] { break } + if d > s[i] { + s[i] = d + changed = true + } } return string(s) } ``` +#### TypeScript + +```ts +function maximumNumber(num: string, change: number[]): string { + const s = num.split(''); + let changed = false; + for (let i = 0; i < s.length; ++i) { + const d = change[+s[i]].toString(); + if (changed && d < s[i]) { + break; + } + if (d > s[i]) { + s[i] = d; + changed = true; + } + } + return s.join(''); +} +``` + +#### Rust + +```rust +impl Solution { + pub fn maximum_number(num: String, change: Vec) -> String { + let mut s: Vec = num.chars().collect(); + let mut changed = false; + for i in 0..s.len() { + let d = (change[s[i] as usize - '0' as usize] + '0' as i32) as u8 as char; + if changed && d < s[i] { + break; + } + if d > s[i] { + changed = true; + s[i] = d; + } + } + s.into_iter().collect() + } +} +``` + +#### JavaScript + +```js +/** + * @param {string} num + * @param {number[]} change + * @return {string} + */ +var maximumNumber = function (num, change) { + const s = num.split(''); + let changed = false; + for (let i = 0; i < s.length; ++i) { + const d = change[+s[i]].toString(); + if (changed && d < s[i]) { + break; + } + if (d > s[i]) { + s[i] = d; + changed = true; + } + } + return s.join(''); +}; +``` + diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.cpp b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.cpp index f4369bd2eb493..56624a89c27c0 100644 --- a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.cpp +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.cpp @@ -2,14 +2,17 @@ class Solution { public: string maximumNumber(string num, vector& change) { int n = num.size(); + bool changed = false; for (int i = 0; i < n; ++i) { - if (change[num[i] - '0'] > num[i] - '0') { - for (; i < n && change[num[i] - '0'] >= num[i] - '0'; ++i) { - num[i] = change[num[i] - '0'] + '0'; - } + char d = '0' + change[num[i] - '0']; + if (changed && d < num[i]) { break; } + if (d > num[i]) { + changed = true; + num[i] = d; + } } return num; } -}; \ No newline at end of file +}; diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.go b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.go index b20e8e0cbb249..17a6e6f47d357 100644 --- a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.go +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.go @@ -1,12 +1,15 @@ func maximumNumber(num string, change []int) string { s := []byte(num) + changed := false for i, c := range num { - if change[c-'0'] > int(c-'0') { - for ; i < len(s) && change[s[i]-'0'] >= int(s[i]-'0'); i++ { - s[i] = byte(change[s[i]-'0']) + '0' - } + d := byte('0' + change[c-'0']) + if changed && d < s[i] { break } + if d > s[i] { + s[i] = d + changed = true + } } return string(s) -} \ No newline at end of file +} diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.java b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.java index 76c99968f24a4..34774087f4684 100644 --- a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.java +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.java @@ -1,14 +1,17 @@ class Solution { public String maximumNumber(String num, int[] change) { char[] s = num.toCharArray(); + boolean changed = false; for (int i = 0; i < s.length; ++i) { - if (change[s[i] - '0'] > s[i] - '0') { - for (; i < s.length && s[i] - '0' <= change[s[i] - '0']; ++i) { - s[i] = (char) (change[s[i] - '0'] + '0'); - } + char d = (char) (change[s[i] - '0'] + '0'); + if (changed && d < s[i]) { break; } + if (d > s[i]) { + changed = true; + s[i] = d; + } } - return String.valueOf(s); + return new String(s); } -} \ No newline at end of file +} diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.js b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.js new file mode 100644 index 0000000000000..090377b9fa747 --- /dev/null +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.js @@ -0,0 +1,20 @@ +/** + * @param {string} num + * @param {number[]} change + * @return {string} + */ +var maximumNumber = function (num, change) { + const s = num.split(''); + let changed = false; + for (let i = 0; i < s.length; ++i) { + const d = change[+s[i]].toString(); + if (changed && d < s[i]) { + break; + } + if (d > s[i]) { + s[i] = d; + changed = true; + } + } + return s.join(''); +}; diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.py b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.py index 1ed9e07401fbb..bd241639ac773 100644 --- a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.py +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.py @@ -1,10 +1,12 @@ class Solution: def maximumNumber(self, num: str, change: List[int]) -> str: s = list(num) + changed = False for i, c in enumerate(s): - if change[int(c)] > int(c): - while i < len(s) and int(s[i]) <= change[int(s[i])]: - s[i] = str(change[int(s[i])]) - i += 1 + d = str(change[int(c)]) + if changed and d < c: break - return ''.join(s) + if d > c: + changed = True + s[i] = d + return "".join(s) diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.rs b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.rs new file mode 100644 index 0000000000000..d7617ebc8b329 --- /dev/null +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.rs @@ -0,0 +1,17 @@ +impl Solution { + pub fn maximum_number(num: String, change: Vec) -> String { + let mut s: Vec = num.chars().collect(); + let mut changed = false; + for i in 0..s.len() { + let d = (change[s[i] as usize - '0' as usize] + '0' as i32) as u8 as char; + if changed && d < s[i] { + break; + } + if d > s[i] { + changed = true; + s[i] = d; + } + } + s.into_iter().collect() + } +} diff --git a/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.ts b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.ts new file mode 100644 index 0000000000000..a096afbbc9b1c --- /dev/null +++ b/solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.ts @@ -0,0 +1,15 @@ +function maximumNumber(num: string, change: number[]): string { + const s = num.split(''); + let changed = false; + for (let i = 0; i < s.length; ++i) { + const d = change[+s[i]].toString(); + if (changed && d < s[i]) { + break; + } + if (d > s[i]) { + s[i] = d; + changed = true; + } + } + return s.join(''); +}