• 图解LeetCode——1417. 重新格式化字符串(难度:简单)


    一、题目

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

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

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

    二、示例

    2.1> 示例 1:

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

    2.2> 示例 2:

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

    2.3> 示例 3:

    【输入】s = "covid2019"
    【输出】"c2o0v1i9d"

    提示:

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

    三、解题思路

    4.1> 思路1:数字集合+字母集合

    根究题意,我们知道字符串中包含了两种类型,即:数字字母。而且,相邻的两个字符不能是相同类型的。那么,最终符合条件的字符串就会是“字母”+“数字”+“字母”+“数字”……这种的字符串了。那么首先,我们需要判断的第一个问题就是,原字符串给我们提供的数字和字母是否能够通过一系列格式化操作,让其变成符合上述条件的字符串呢?其实如果想符合字母与数字相互穿插的新字符串,其实只需要满足两种情况:

    情况一:字母总个数等于数字个总数。此时无论是字母还是数字,谁是第一个都无所谓。
    情况二:字母总个数与数字总个数相差一个字符。那么,如果再仔细剖析,我们会发现,如果字母总个数比数字的总个数大于1个,那么最终结合出来的新字符串的第一个位置一定是字符。而如果数字的总个数比字母的总个数大于1个,那么最终结合出来的新的字符串的第一个位置就一定是数字了。

    通过上面的分析,我们首要的第一个步骤就是拆分原有字符串,将所有字母都放到字母集合——words中;将所有数字都放到数字集合——nums中;我们以s=“covid2019”为例,下面是具体的拆分情况:

    既然拆分出了字母集合和数字集合,那么我们就可以根据他们各自的size()来判断是否可以组成字母与数字相间的字符串。也就是说,当wordsnums他们两者之间的长度差距大于1个字符,则无论怎么拼装,都不会满足题目要求的最终字符串了,那么这种情况,直接方法返回空的字符串——“”。那么,如果两者之间长度等于1,无论是字母集合多了一个字符,还是数字集合多了一个字符,我们都把那个多的集合的最后一个字符存储到lastChar变量中。当然,如果words和nums两者之间的长度相同,则lastChar就是默认值“”。具体操作如下图所示:

    好了,通过上面的一些操作之后,wordsnums需要拼装的部分长度就相同了(因为我们把多出的那一个字符保存到了lastChar里了)。通过循环遍历,将words和nums进行拼装,拼装方式就是——如果是字母个数较大,那么拼装顺序就是“字母”+“数字”;如果是数字个数较大,那么拼装顺序就是“数字”+“字母”;具体操作如下图所示:

    当全都拼装完毕后,最后将lastChar放到最终字符串的末尾处

    具体代码实现,请参见4.1> 实现1:数字集合 + 字母集合

    4.2> 思路2:奇数位 + 偶数位

    在4.1的处理逻辑中,我们发现还是比较麻烦的,并且代码量也不少,执行时间也比较慢。那么,还有什么更好的解题思路吗?肯定是有的。这里,我们不去将字母和数字存储到两个集合中了。我们借用奇数位偶数位来将字母或者数字插入到新的char数组中。与上面解法不同,我们只需要计算出字母出现的个数charNums和数字出现的个数nums。如果字母个数更大,则字母插入到奇数位,数字插入到偶数位;如果数字的个数更大,则数字插入到奇数位,字母插入到偶数位。具体操作,如下图所示:

    具体代码实现,请参见4.2> 实现1:奇数位 + 偶数位

    四、代码实现

    4.1> 实现1:数字集合 + 字母集合

    1. class Solution {
    2.     public String reformat(String s) {
    3.         List words = new ArrayList();
    4.         List nums = new ArrayList();
    5.         for (int i = 0; i < s.length(); i++) {
    6.             if (Character.isDigit(s.charAt(i))) {
    7.                 nums.add(s.charAt(i));
    8.             } else {
    9.                 words.add(s.charAt(i));
    10.             }
    11.         }
    12.         int absNums = Math.abs(words.size() - nums.size());
    13.         if (absNums != 0 && absNums != 1return "";
    14.         String lastChar = "";
    15.         boolean wordFirst = false;
    16.         if (words.size() - nums.size() == 1) {
    17.             lastChar = "" + words.get(words.size() - 1);
    18.             wordFirst = true;
    19.         } else if (nums.size() - words.size() == 1) {
    20.             lastChar = "" + nums.get(nums.size() - 1);
    21.         }
    22.         StringBuilder result = new StringBuilder();
    23.         for (int i = 0; i < Math.min(words.size(), nums.size()); i++) {
    24.             if (wordFirst) {
    25.                 result.append(words.get(i) == null ? "" : words.get(i));
    26.                 result.append(nums.get(i) == null ? "" : nums.get(i));
    27.             } else {
    28.                 result.append(nums.get(i) == null ? "" : nums.get(i));
    29.                 result.append(words.get(i) == null ? "" : words.get(i));                
    30.             }
    31.         }
    32.         return result.append(lastChar).toString();
    33.     }
    34. }

    4.2> 实现2:奇数位 + 偶数位

    1. class Solution {
    2.     public String reformat(String s) {
    3.         int charNums = 0, nums = 0;
    4.         for (int i = 0; i < s.length(); i++) {
    5.             if (Character.isDigit(s.charAt(i))) nums++;
    6.             else charNums++;
    7.         }
    8.         if (Math.abs(charNums - nums) > 1return "";
    9.         int charIndex = 0, numIndex = 0;
    10.         if(charNums > nums) numIndex = 1;
    11.         else charIndex = 1;
    12.         char[] result = new char[s.length()];
    13.         for (int i = 0; i < s.length(); i++) {
    14.             if (Character.isDigit(s.charAt(i))) {
    15.                 result[numIndex] = s.charAt(i);
    16.                 numIndex += 2;
    17.             } else {
    18.                 result[charIndex] = s.charAt(i);
    19.                 charIndex += 2;
    20.             }
    21.         }
    22.         return new String(result);
    23.     }
    24. }

    今天的文章内容就这些了:

    写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。

    更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」

  • 相关阅读:
    获取 Android 手机屏幕的实际大小(英寸)
    HTML期末作业 计算机毕业设计——简单的学生网页作业源码 基于HTML品优购项目的设计与实现(7页)
    【LeetCode刷题(数据结构与算法)】:将二叉搜索树转化为排序的双向链表
    【Flink源码】Flink心跳机制
    Python:打印目录下每层的文件总数
    How to use UMDH to test memory leak
    网络攻防原理与技术 第一章 课后题
    MySQL-1-SQL讲解
    【服务器 | 测试】如何在centos 7上面安装jmeter
    【SpringBoot】YAML 配置文件
  • 原文地址:https://blog.csdn.net/qq_26470817/article/details/126295228