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('');
+}