给你一个混合了数字和字母的字符串 s
,其中的字母均为小写英文字母。
请你将该字符串重新格式化,使得任意两个相邻字符的类型都不同。也就是说,字母后面应该跟着数字,而数字后面应该跟着字母。
请你返回 重新格式化后 的字符串;如果无法按要求重新格式化,则返回一个 空字符串 。
【输入】s = "a0b1c2"
【输出】"0a1b2c"
【解释】"0a1b2c" 中任意两个相邻字符的类型都不同。 "a0b1c2", "0a1b2c", "0c2a1b" 也是满足题目要求的答案。
【输入】s = "leetcode"
【输出】""
【解释】"leetcode" 中只有字母,所以无法满足重新格式化的条件。
【输入】s = "covid2019"
【输出】"c2o0v1i9d"
1
<= s.length <=500
s
仅由小写英文字母和/或数字组成。
根究题意,我们知道字符串中包含了两种类型,即:数字和字母。而且,相邻的两个字符不能是相同类型的。那么,最终符合条件的字符串就会是“字母”+“数字”+“字母”+“数字”……
这种的字符串了。那么首先,我们需要判断的第一个问题就是,原字符串给我们提供的数字和字母是否能够通过一系列格式化操作,让其变成符合上述条件的字符串呢?其实如果想符合字母与数字相互穿插的新字符串,其实只需要满足两种情况:
情况一:字母总个数等于数字个总数。此时无论是字母还是数字,谁是第一个都无所谓。
情况二:字母总个数与数字总个数相差一个字符。那么,如果再仔细剖析,我们会发现,如果字母总个数比数字的总个数大于1个,那么最终结合出来的新字符串的第一个位置一定是字符。而如果数字的总个数比字母的总个数大于1个,那么最终结合出来的新的字符串的第一个位置就一定是数字了。
通过上面的分析,我们首要的第一个步骤就是拆分原有字符串,将所有字母都放到字母集合——words
中;将所有数字都放到数字集合——nums
中;我们以s=“covid2019”为例,下面是具体的拆分情况:
既然拆分出了字母集合和数字集合,那么我们就可以根据他们各自的size()
来判断是否可以组成字母与数字相间的字符串。也就是说,当words
和nums
他们两者之间的长度差距大于1个字符,则无论怎么拼装,都不会满足题目要求的最终字符串了,那么这种情况,直接方法返回空的字符串——“”。那么,如果两者之间长度等于1,无论是字母集合多了一个字符,还是数字集合多了一个字符,我们都把那个多的集合的最后一个字符存储到lastChar
变量中。当然,如果words和nums两者之间的长度相同,则lastChar
就是默认值“”。具体操作如下图所示:
好了,通过上面的一些操作之后,words
和nums
需要拼装的部分长度就相同了(因为我们把多出的那一个字符保存到了lastChar里了)。通过循环遍历,将words和nums进行拼装,拼装方式就是——如果是字母个数较大,那么拼装顺序就是“字母”+“数字”
;如果是数字个数较大,那么拼装顺序就是“数字”+“字母”
;具体操作如下图所示:
当全都拼装完毕后,最后将lastChar放到最终字符串的末尾处。
具体代码实现,请参见4.1> 实现1:数字集合 + 字母集合
在4.1的处理逻辑中,我们发现还是比较麻烦的,并且代码量也不少,执行时间也比较慢。那么,还有什么更好的解题思路吗?肯定是有的。这里,我们不去将字母和数字存储到两个集合中了。我们借用奇数位
和偶数位
来将字母或者数字插入到新的char数组
中。与上面解法不同,我们只需要计算出字母出现的个数charNums和数字出现的个数nums。如果字母个数更大,则字母插入到奇数位,数字插入到偶数位;如果数字的个数更大,则数字插入到奇数位,字母插入到偶数位。具体操作,如下图所示:
具体代码实现,请参见4.2> 实现1:奇数位 + 偶数位
- class Solution {
- public String reformat(String s) {
- List
words = new ArrayList(); - List
nums = new ArrayList(); -
- for (int i = 0; i < s.length(); i++) {
- if (Character.isDigit(s.charAt(i))) {
- nums.add(s.charAt(i));
- } else {
- words.add(s.charAt(i));
- }
- }
-
- int absNums = Math.abs(words.size() - nums.size());
- if (absNums != 0 && absNums != 1) return "";
-
- String lastChar = "";
- boolean wordFirst = false;
- if (words.size() - nums.size() == 1) {
- lastChar = "" + words.get(words.size() - 1);
- wordFirst = true;
- } else if (nums.size() - words.size() == 1) {
- lastChar = "" + nums.get(nums.size() - 1);
- }
-
- StringBuilder result = new StringBuilder();
- for (int i = 0; i < Math.min(words.size(), nums.size()); i++) {
- if (wordFirst) {
- result.append(words.get(i) == null ? "" : words.get(i));
- result.append(nums.get(i) == null ? "" : nums.get(i));
- } else {
- result.append(nums.get(i) == null ? "" : nums.get(i));
- result.append(words.get(i) == null ? "" : words.get(i));
- }
- }
-
- return result.append(lastChar).toString();
- }
- }
- class Solution {
- public String reformat(String s) {
- int charNums = 0, nums = 0;
- for (int i = 0; i < s.length(); i++) {
- if (Character.isDigit(s.charAt(i))) nums++;
- else charNums++;
- }
- if (Math.abs(charNums - nums) > 1) return "";
-
- int charIndex = 0, numIndex = 0;
- if(charNums > nums) numIndex = 1;
- else charIndex = 1;
-
- char[] result = new char[s.length()];
- for (int i = 0; i < s.length(); i++) {
- if (Character.isDigit(s.charAt(i))) {
- result[numIndex] = s.charAt(i);
- numIndex += 2;
- } else {
- result[charIndex] = s.charAt(i);
- charIndex += 2;
- }
- }
- return new String(result);
- }
- }
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」