Skip to content

Commit 3550db3

Browse files
authored
feat: add solutions to lc problem: No.1946 (#4028)
No.1946.Largest Number After Mutating Substring
1 parent 1060b58 commit 3550db3

File tree

9 files changed

+296
-61
lines changed

9 files changed

+296
-61
lines changed

Diff for: solution/1900-1999/1946.Largest Number After Mutating Substring/README.md

+105-21
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ tags:
4949
- 2 映射为 change[2] = 3 。
5050
- 1 映射为 change[1] = 4 。
5151
因此,"<strong><em>021</em></strong>" 变为 "<strong><em>934</em></strong>" 。
52-
"934" 是可以构造的最大整数,所以返回它的字符串表示。
52+
"934" 是可以构造的最大整数,所以返回它的字符串表示。
5353
</pre>
5454

5555
<p><strong>示例 3:</strong></p>
@@ -78,9 +78,15 @@ tags:
7878

7979
### 方法一:贪心
8080

81-
从左到右遍历字符串 `num`,找到第一个比 `change` 中对应数字小的数字,然后将其替换为 `change` 中对应的数字,直到遇到比 `change` 中对应数字大的数字,停止替换
81+
根据题目描述,我们可以从字符串的高位开始,贪心的进行连续的替换操作,直到遇到一个比当前位数字小的数字为止
8282

83-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 `num` 的长度。
83+
我们先将字符串 $\textit{num}$ 转换为字符数组 $\textit{s}$,用一个变量 $\textit{changed}$ 记录是否已经发生过变化,初始时 $\textit{changed} = \text{false}$。
84+
85+
然后我们遍历字符数组 $\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}$。
86+
87+
最后我们将字符数组 $\textit{s}$ 转换为字符串并返回即可。
88+
89+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为字符串 $\textit{num}$ 的长度。
8490

8591
<!-- tabs:start -->
8692

@@ -90,13 +96,15 @@ tags:
9096
class Solution:
9197
def maximumNumber(self, num: str, change: List[int]) -> str:
9298
s = list(num)
99+
changed = False
93100
for i, c in enumerate(s):
94-
if change[int(c)] > int(c):
95-
while i < len(s) and int(s[i]) <= change[int(s[i])]:
96-
s[i] = str(change[int(s[i])])
97-
i += 1
101+
d = str(change[int(c)])
102+
if changed and d < c:
98103
break
99-
return ''.join(s)
104+
if d > c:
105+
changed = True
106+
s[i] = d
107+
return "".join(s)
100108
```
101109

102110
#### Java
@@ -105,15 +113,18 @@ class Solution:
105113
class Solution {
106114
public String maximumNumber(String num, int[] change) {
107115
char[] s = num.toCharArray();
116+
boolean changed = false;
108117
for (int i = 0; i < s.length; ++i) {
109-
if (change[s[i] - '0'] > s[i] - '0') {
110-
for (; i < s.length && s[i] - '0' <= change[s[i] - '0']; ++i) {
111-
s[i] = (char) (change[s[i] - '0'] + '0');
112-
}
118+
char d = (char) (change[s[i] - '0'] + '0');
119+
if (changed && d < s[i]) {
113120
break;
114121
}
122+
if (d > s[i]) {
123+
changed = true;
124+
s[i] = d;
125+
}
115126
}
116-
return String.valueOf(s);
127+
return new String(s);
117128
}
118129
}
119130
```
@@ -125,13 +136,16 @@ class Solution {
125136
public:
126137
string maximumNumber(string num, vector<int>& change) {
127138
int n = num.size();
139+
bool changed = false;
128140
for (int i = 0; i < n; ++i) {
129-
if (change[num[i] - '0'] > num[i] - '0') {
130-
for (; i < n && change[num[i] - '0'] >= num[i] - '0'; ++i) {
131-
num[i] = change[num[i] - '0'] + '0';
132-
}
141+
char d = '0' + change[num[i] - '0'];
142+
if (changed && d < num[i]) {
133143
break;
134144
}
145+
if (d > num[i]) {
146+
changed = true;
147+
num[i] = d;
148+
}
135149
}
136150
return num;
137151
}
@@ -143,18 +157,88 @@ public:
143157
```go
144158
func maximumNumber(num string, change []int) string {
145159
s := []byte(num)
160+
changed := false
146161
for i, c := range num {
147-
if change[c-'0'] > int(c-'0') {
148-
for ; i < len(s) && change[s[i]-'0'] >= int(s[i]-'0'); i++ {
149-
s[i] = byte(change[s[i]-'0']) + '0'
150-
}
162+
d := byte('0' + change[c-'0'])
163+
if changed && d < s[i] {
151164
break
152165
}
166+
if d > s[i] {
167+
s[i] = d
168+
changed = true
169+
}
153170
}
154171
return string(s)
155172
}
156173
```
157174

175+
#### TypeScript
176+
177+
```ts
178+
function maximumNumber(num: string, change: number[]): string {
179+
const s = num.split('');
180+
let changed = false;
181+
for (let i = 0; i < s.length; ++i) {
182+
const d = change[+s[i]].toString();
183+
if (changed && d < s[i]) {
184+
break;
185+
}
186+
if (d > s[i]) {
187+
s[i] = d;
188+
changed = true;
189+
}
190+
}
191+
return s.join('');
192+
}
193+
```
194+
195+
#### Rust
196+
197+
```rust
198+
impl Solution {
199+
pub fn maximum_number(num: String, change: Vec<i32>) -> String {
200+
let mut s: Vec<char> = num.chars().collect();
201+
let mut changed = false;
202+
for i in 0..s.len() {
203+
let d = (change[s[i] as usize - '0' as usize] + '0' as i32) as u8 as char;
204+
if changed && d < s[i] {
205+
break;
206+
}
207+
if d > s[i] {
208+
changed = true;
209+
s[i] = d;
210+
}
211+
}
212+
s.into_iter().collect()
213+
}
214+
}
215+
```
216+
217+
#### JavaScript
218+
219+
```js
220+
/**
221+
* @param {string} num
222+
* @param {number[]} change
223+
* @return {string}
224+
*/
225+
var maximumNumber = function (num, change) {
226+
const s = num.split('');
227+
let changed = false;
228+
for (let i = 0; i < s.length; ++i) {
229+
const d = change[+s[i]].toString();
230+
if (changed && d < s[i]) {
231+
break;
232+
}
233+
if (d > s[i]) {
234+
s[i] = d;
235+
changed = true;
236+
}
237+
}
238+
return s.join('');
239+
};
240+
```
241+
158242
<!-- tabs:end -->
159243

160244
<!-- solution:end -->

Diff for: solution/1900-1999/1946.Largest Number After Mutating Substring/README_EN.md

+107-19
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,17 @@ Thus, &quot;<u>021</u>&quot; becomes &quot;<u>934</u>&quot;.
7777

7878
<!-- solution:start -->
7979

80-
### Solution 1
80+
### Solution 1: Greedy
81+
82+
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.
83+
84+
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}$.
85+
86+
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}$.
87+
88+
Finally, we convert the character array $\textit{s}$ back to a string and return it.
89+
90+
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string $\textit{num}$.
8191

8292
<!-- tabs:start -->
8393

@@ -87,13 +97,15 @@ Thus, &quot;<u>021</u>&quot; becomes &quot;<u>934</u>&quot;.
8797
class Solution:
8898
def maximumNumber(self, num: str, change: List[int]) -> str:
8999
s = list(num)
100+
changed = False
90101
for i, c in enumerate(s):
91-
if change[int(c)] > int(c):
92-
while i < len(s) and int(s[i]) <= change[int(s[i])]:
93-
s[i] = str(change[int(s[i])])
94-
i += 1
102+
d = str(change[int(c)])
103+
if changed and d < c:
95104
break
96-
return ''.join(s)
105+
if d > c:
106+
changed = True
107+
s[i] = d
108+
return "".join(s)
97109
```
98110

99111
#### Java
@@ -102,15 +114,18 @@ class Solution:
102114
class Solution {
103115
public String maximumNumber(String num, int[] change) {
104116
char[] s = num.toCharArray();
117+
boolean changed = false;
105118
for (int i = 0; i < s.length; ++i) {
106-
if (change[s[i] - '0'] > s[i] - '0') {
107-
for (; i < s.length && s[i] - '0' <= change[s[i] - '0']; ++i) {
108-
s[i] = (char) (change[s[i] - '0'] + '0');
109-
}
119+
char d = (char) (change[s[i] - '0'] + '0');
120+
if (changed && d < s[i]) {
110121
break;
111122
}
123+
if (d > s[i]) {
124+
changed = true;
125+
s[i] = d;
126+
}
112127
}
113-
return String.valueOf(s);
128+
return new String(s);
114129
}
115130
}
116131
```
@@ -122,13 +137,16 @@ class Solution {
122137
public:
123138
string maximumNumber(string num, vector<int>& change) {
124139
int n = num.size();
140+
bool changed = false;
125141
for (int i = 0; i < n; ++i) {
126-
if (change[num[i] - '0'] > num[i] - '0') {
127-
for (; i < n && change[num[i] - '0'] >= num[i] - '0'; ++i) {
128-
num[i] = change[num[i] - '0'] + '0';
129-
}
142+
char d = '0' + change[num[i] - '0'];
143+
if (changed && d < num[i]) {
130144
break;
131145
}
146+
if (d > num[i]) {
147+
changed = true;
148+
num[i] = d;
149+
}
132150
}
133151
return num;
134152
}
@@ -140,18 +158,88 @@ public:
140158
```go
141159
func maximumNumber(num string, change []int) string {
142160
s := []byte(num)
161+
changed := false
143162
for i, c := range num {
144-
if change[c-'0'] > int(c-'0') {
145-
for ; i < len(s) && change[s[i]-'0'] >= int(s[i]-'0'); i++ {
146-
s[i] = byte(change[s[i]-'0']) + '0'
147-
}
163+
d := byte('0' + change[c-'0'])
164+
if changed && d < s[i] {
148165
break
149166
}
167+
if d > s[i] {
168+
s[i] = d
169+
changed = true
170+
}
150171
}
151172
return string(s)
152173
}
153174
```
154175

176+
#### TypeScript
177+
178+
```ts
179+
function maximumNumber(num: string, change: number[]): string {
180+
const s = num.split('');
181+
let changed = false;
182+
for (let i = 0; i < s.length; ++i) {
183+
const d = change[+s[i]].toString();
184+
if (changed && d < s[i]) {
185+
break;
186+
}
187+
if (d > s[i]) {
188+
s[i] = d;
189+
changed = true;
190+
}
191+
}
192+
return s.join('');
193+
}
194+
```
195+
196+
#### Rust
197+
198+
```rust
199+
impl Solution {
200+
pub fn maximum_number(num: String, change: Vec<i32>) -> String {
201+
let mut s: Vec<char> = num.chars().collect();
202+
let mut changed = false;
203+
for i in 0..s.len() {
204+
let d = (change[s[i] as usize - '0' as usize] + '0' as i32) as u8 as char;
205+
if changed && d < s[i] {
206+
break;
207+
}
208+
if d > s[i] {
209+
changed = true;
210+
s[i] = d;
211+
}
212+
}
213+
s.into_iter().collect()
214+
}
215+
}
216+
```
217+
218+
#### JavaScript
219+
220+
```js
221+
/**
222+
* @param {string} num
223+
* @param {number[]} change
224+
* @return {string}
225+
*/
226+
var maximumNumber = function (num, change) {
227+
const s = num.split('');
228+
let changed = false;
229+
for (let i = 0; i < s.length; ++i) {
230+
const d = change[+s[i]].toString();
231+
if (changed && d < s[i]) {
232+
break;
233+
}
234+
if (d > s[i]) {
235+
s[i] = d;
236+
changed = true;
237+
}
238+
}
239+
return s.join('');
240+
};
241+
```
242+
155243
<!-- tabs:end -->
156244

157245
<!-- solution:end -->

Diff for: solution/1900-1999/1946.Largest Number After Mutating Substring/Solution.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ class Solution {
22
public:
33
string maximumNumber(string num, vector<int>& change) {
44
int n = num.size();
5+
bool changed = false;
56
for (int i = 0; i < n; ++i) {
6-
if (change[num[i] - '0'] > num[i] - '0') {
7-
for (; i < n && change[num[i] - '0'] >= num[i] - '0'; ++i) {
8-
num[i] = change[num[i] - '0'] + '0';
9-
}
7+
char d = '0' + change[num[i] - '0'];
8+
if (changed && d < num[i]) {
109
break;
1110
}
11+
if (d > num[i]) {
12+
changed = true;
13+
num[i] = d;
14+
}
1215
}
1316
return num;
1417
}
15-
};
18+
};

0 commit comments

Comments
 (0)