携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
给你一个混合了数字和字母的字符串 s,其中的字母均为小写英文字母。
请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。
请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串 。
示例 1:
输入:s = "a0b1c2"
输出:"0a1b2c"
解释:"0a1b2c" 中任意两个相邻字符的类型都不同。 "a0b1c2", "0a1b2c", "0c2a1b" 也是满足题目要求的答案。
示例 2:
输入:s = "leetcode"
输出:""
解释:"leetcode" 中只有字母,所以无法满足重新格式化的条件。
示例 3:
输入:s = "1229857369"
输出:""
解释:"1229857369" 中只有数字,所以无法满足重新格式化的条件。
双指针
题目给定字符串 ,我们记 为字符串中数字的个数, 为字符串中字母的个数。那么能按照题目要求格式化字符串的充要条件为:
那么当给定字符串 满足上述条件时,我们把数字和字母中个数多的放在偶数位上(字符串下标从 开始),个数少的放在奇数位上,此时可以构造出满足题目条件的字符串。那么我们用 和 来分别表示个数多的和个数少的字符放置的下标,初始为 ,然后从左到右移动 ,当 为个数少的字符类型时,那么向右移动 找到往后的第一个 为个数多的字符类型,然后交换两个字符即可,不断重复该过程直至 移动到字符串结尾即可。
var reformat = function(s) {
let sumDigit = 0;
for (let i = 0; i < s.length; i++) {
const c = s[i];
if (isDigit(c)) {
sumDigit++;
}
}
let sumAlpha = s.length - sumDigit;
if (Math.abs(sumDigit - sumAlpha) > 1) {
return "";
}
let flag = sumDigit > sumAlpha;
const arr = [...s];
for (let i = 0, j = 1; i < s.length; i += 2) {
if (isDigit(arr[i]) !== flag) {
while (isDigit(arr[j]) !== flag) {
j += 2;
}
[arr[i], arr[j]] = [arr[j], arr[i]];
}
}
return arr.join('');
}
const isDigit = (ch) => {
return parseFloat(ch).toString() === "NaN" ? false : true;
}