题目是LeetCode第185场周赛的第一题,链接:重新格式化字符串。具体描述为:给你一个混合了数字和字母的字符串 s,其中的字母均为小写英文字母。请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串 。
示例1:
输入:s = "a0b1c2"
输出:"0a1b2c"
解释:"0a1b2c" 中任意两个相邻字符的类型都不同。 "a0b1c2", "0a1b2c", "0c2a1b" 也是满足题目要求的答案。
示例2:
输入:s = "leetcode"
输出:""
解释:"leetcode" 中只有字母,所以无法满足重新格式化的条件。
示例3:
输入:s = "1229857369"
输出:""
解释:"1229857369" 中只有数字,所以无法满足重新格式化的条件。
题目很简单,直接统计字符串中数字和字母的数目,若有一个的数目超过了总数目的一半(奇数情况下的一半定义为+1后除以2,比如5的一半定义为3),说明无法满足重新格式化的条件,可以直接返回空字符串。然后再根据数字和字母的多少,先排列多的再排小的即可。时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)。
JAVA版代码如下:
class Solution {
public String reformat(String s) {
char[] chars = s.toCharArray();
char[] strs = new char[(chars.length + 1) / 2];
char[] nums = new char[(chars.length + 1) / 2];
int strIdx = 0, numIdx = 0;
for (char c : chars) {
if (c >= 'a' && c <= 'z') {
if (strIdx >= strs.length) {
return "";
}
strs[strIdx++] = c;
}
else {
if (numIdx >= strs.length) {
return "";
}
nums[numIdx++] = c;
}
}
char[] result = new char[strIdx + numIdx];
if (strIdx >= numIdx) {
for (int i = 0; i < strIdx; ++i) {
result[2 * i] = strs[i];
}
for (int i = 0; i < numIdx; ++i) {
result[2 * i + 1] = nums[i];
}
}
else {
for (int i = 0; i < numIdx; ++i) {
result[2 * i] = nums[i];
}
for (int i = 0; i < strIdx; ++i) {
result[2 * i + 1] = strs[i];
}
}
return new String(result);
}
}
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/c10ad1a3e97bd868c69ee175d664cb2e.png)
Python版代码如下:
class Solution:
def reformat(self, s: str) -> str:
nums = list(filter(lambda x : x.isdigit(), s))
letters = list(filter(lambda x : x.isalpha(), s))
numLen = len(nums)
letterLen = len(letters)
if abs(numLen - letterLen) > 1:
return ''
result = ''
if numLen < letterLen:
for i in range(numLen):
result += letters[i]
result += nums[i]
result += letters[-1]
else:
for i in range(letterLen):
result += nums[i]
result += letters[i]
if numLen > letterLen:
result += nums[-1]
return result
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/c1d25d8d92f05a91b1f9ad753e69f8ab.png)