Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.1946 (#4028)
Browse files Browse the repository at this point in the history
No.1946.Largest Number After Mutating Substring
  • Loading branch information
yanglbme authored Feb 5, 2025
1 parent 1060b58 commit 3550db3
Show file tree
Hide file tree
Showing 9 changed files with 296 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ tags:
- 2 映射为 change[2] = 3 。
- 1 映射为 change[1] = 4 。
因此,"<strong><em>021</em></strong>" 变为 "<strong><em>934</em></strong>" 。
"934" 是可以构造的最大整数,所以返回它的字符串表示。
"934" 是可以构造的最大整数,所以返回它的字符串表示。
</pre>

<p><strong>示例 3:</strong></p>
Expand Down Expand Up @@ -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}$ 的长度。

<!-- tabs:start -->

Expand All @@ -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
Expand All @@ -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);
}
}
```
Expand All @@ -125,13 +136,16 @@ class Solution {
public:
string maximumNumber(string num, vector<int>& 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;
}
Expand All @@ -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<i32>) -> String {
let mut s: Vec<char> = 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('');
};
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,17 @@ Thus, &quot;<u>021</u>&quot; becomes &quot;<u>934</u>&quot;.

<!-- solution:start -->

### 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}$.

<!-- tabs:start -->

Expand All @@ -87,13 +97,15 @@ Thus, &quot;<u>021</u>&quot; becomes &quot;<u>934</u>&quot;.
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
Expand All @@ -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);
}
}
```
Expand All @@ -122,13 +137,16 @@ class Solution {
public:
string maximumNumber(string num, vector<int>& 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;
}
Expand All @@ -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<i32>) -> String {
let mut s: Vec<char> = 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('');
};
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ class Solution {
public:
string maximumNumber(string num, vector<int>& 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;
}
};
};
Loading

0 comments on commit 3550db3

Please sign in to comment.