Easy
题目描述
给你一个仅由数字组成的字符串 s,返回在将 s 中具有相同奇偶性的相邻数字交换 至多一次 后,可以得到的字典序最小的字符串。
如果两个数字都是奇数或都是偶数,则它们具有相同的奇偶性。例如,5 和 9、以及 2 和 4 奇偶性相同,而 6 和 9 奇偶性不同。
示例 1:
输入:s = "45320"
输出:"43520"
解释:s[1] == '5' 和 s[2] == '3' 都是奇数,交换它们可以得到字典序最小的字符串。
示例 2:
输入:s = "001"
输出:"001"
解释:无需进行交换,因为 s 已经是字典序最小的。
提示:
2 <= s.length <= 100s仅由数字组成
解题思路
这道题要求我们通过最多一次交换相邻且具有相同奇偶性的数字,得到字典序最小的字符串。
核心思路:
- 贪心策略:为了得到字典序最小的字符串,我们应该尽可能让前面的位置放置更小的数字。
- 从左到右遍历:遍历字符串的每个位置 i,检查位置 i 和 i+1 的数字是否具有相同奇偶性。
- 交换条件:如果 s[i] > s[i+1] 且它们奇偶性相同,那么交换它们可以让字符串变得更小。
- 最多一次交换:由于只能交换一次,找到第一个满足条件的位置就立即交换并返回。
算法步骤:
- 遍历字符串,对于每个位置 i(0 ≤ i < n-1)
- 检查 s[i] 和 s[i+1] 是否满足:s[i] > s[i+1] 且奇偶性相同
- 如果满足条件,交换这两个字符并返回结果
- 如果遍历完都没有找到可交换的位置,返回原字符串
时间复杂度为 O(n),空间复杂度为 O(1)(不考虑结果字符串的空间)。
代码实现
class Solution {
public:
string getSmallestString(string s) {
int n = s.length();
for (int i = 0; i < n - 1; i++) {
int digit1 = s[i] - '0';
int digit2 = s[i + 1] - '0';
// 检查奇偶性是否相同且第一个数字大于第二个数字
if ((digit1 % 2 == digit2 % 2) && digit1 > digit2) {
swap(s[i], s[i + 1]);
return s;
}
}
return s;
}
};
class Solution:
def getSmallestString(self, s: str) -> str:
s = list(s)
n = len(s)
for i in range(n - 1):
digit1 = int(s[i])
digit2 = int(s[i + 1])
# 检查奇偶性是否相同且第一个数字大于第二个数字
if (digit1 % 2 == digit2 % 2) and digit1 > digit2:
s[i], s[i + 1] = s[i + 1], s[i]
return ''.join(s)
return ''.join(s)
public class Solution {
public string GetSmallestString(string s) {
char[] chars = s.ToCharArray();
int n = chars.Length;
for (int i = 0; i < n - 1; i++) {
int digit1 = chars[i] - '0';
int digit2 = chars[i + 1] - '0';
// 检查奇偶性是否相同且第一个数字大于第二个数字
if ((digit1 % 2 == digit2 % 2) && digit1 > digit2) {
char temp = chars[i];
chars[i] = chars[i + 1];
chars[i + 1] = temp;
return new string(chars);
}
}
return s;
}
}
/**
* @param {string} s
* @return {string}
*/
var getSmallestString = function(s) {
let arr = s.split('');
for (let i = 0; i < arr.length - 1; i++) {
let curr = parseInt(arr[i]);
let next = parseInt(arr[i + 1]);
if (curr % 2 === next % 2 && curr > next) {
[arr[i], arr[i + 1]] = [arr[i + 1], arr[i]];
break;
}
}
return arr.join('');
};
复杂度分析
| 复杂度类型 | 复杂度 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(1) 或 O(n) |
说明:
- 时间复杂度:O(n),其中 n 是字符串的长度,最多需要遍历一次字符串
- 空间复杂度:对于 C++ 可以原地修改为 O(1);对于 Python、C#、JavaScript 需要创建字符数组,为 O(n)