侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 471 篇文章
  • 累计创建 108 个标签
  • 累计收到 9 条评论

目 录CONTENT

文章目录

【字符串, 计数】重新格式化字符串

GabrielxD
2022-08-11 / 0 评论 / 0 点赞 / 48 阅读 / 933 字 / 正在检测是否收录...

题目

1417. 重新格式化字符串


给你一个混合了数字和字母的字符串 s,其中的字母均为小写英文字母。

请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。

请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串

示例 1:

输入:s = "a0b1c2"
输出:"0a1b2c"
解释:"0a1b2c" 中任意两个相邻字符的类型都不同。 "a0b1c2", "0a1b2c", "0c2a1b" 也是满足题目要求的答案。

示例 2:

输入:s = "leetcode"
输出:""
解释:"leetcode" 中只有字母,所以无法满足重新格式化的条件。

示例 3:

输入:s = "1229857369"
输出:""
解释:"1229857369" 中只有数字,所以无法满足重新格式化的条件。

示例 4:

输入:s = "covid2019"
输出:"c2o0v1i9d"

示例 5:

输入:s = "ab123"
输出:"1a2b3"

提示:

  • 1 <= s.length <= 500
  • s 仅由小写英文字母和/或数字组成。

解题

方法一:计数

思路

遍历字符串,数出数字的数量(num_count)和字母的数量(alp_count),如果数字数量和字母数量相差大于 1 ,那么绝对无法重新格式化,直接返回空字符串。

否则新建一个和原字符串等长的字符串(ans)用于之后替换字符形成答案,然后维护一个在新字符串中要放入字母的下标(i),放入数字的下标(j)。假设新字符串中字符的下标为 [0, n-1]那么当数字和字母数量相差 1 时,较多的那种字符应该放入偶数位,较少的那种字符应该放入奇数位,按照这个思路初始化 i, j 并再次遍历原字符串,把字符放入对应的位置。

代码

class Solution {
public:
    string reformat(string s) {
        int num_count = 0, alp_count = 0;
        for (char& ch : s) {
            if (ch >= '0' && ch <= '9') ++num_count;
            else ++alp_count;
        }
        if (abs(num_count - alp_count) > 1) return "";
        string ans(s);
        int i = num_count > alp_count, j = !i;
        for (char& ch : s) {
            if (ch >= '0' && ch <= '9') {
                ans[j] = ch;
                j += 2;
            } else {
                ans[i] = ch;
                i += 2;
            }
        }
        return ans;
    }
};
class Solution {
    public String reformat(String s) {
        char[] chs = s.toCharArray();
        int numCount = 0, alpCount = 0;
        for (char ch : chs) {
            if (ch >= '0' && ch <= '9') ++numCount;
            else ++alpCount;
        }
        if (Math.abs(numCount - alpCount) > 1) return "";
        char[] ans = new char[chs.length];
        int i = 0, j = 0;
        if (numCount > alpCount) i = 1;
        else j = 1;
        for (char ch : chs) {
            if (ch >= '0' && ch <= '9') {
                ans[j] = ch;
                j += 2;
            } else {
                ans[i] = ch;
                i += 2;
            }
        }
        return String.valueOf(ans);
    }
}

方法二:计数 链表(不推荐)

思路

一开始自己想到的笨办法,把两种字符分别存入两个链表,然后再分别取出来构建新字符串,其他部分和上面一样。

代码

class Solution {
public:
    string reformat(string s) {
        int num_count = 0, alp_count = 0;
        forward_list<char> nums, alps;
        for (char& ch : s) {
            if (ch >= '0' && ch <= '9') {
                nums.push_front(ch);
                ++num_count;
            } else {
                alps.push_front(ch);
                ++alp_count;
            }
        }
        if (abs(num_count - alp_count) > 1) return "";
        string ans;
        if (num_count < alp_count) swap(nums, alps);
        for (int i = num_count + alp_count; i >= 1; --i ) {
            if (i & 1) {
                ans += nums.front();
                nums.pop_front();
            } else {
                ans += alps.front();
                alps.pop_front();
            }
        }
        return ans;
    }
};
0

评论区