ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

字符串题目:重新格式化电话号码

2021-11-25 18:02:21  阅读:221  来源: 互联网

标签:格式化 数字 texttt number 456 123 电话号码 字符串


文章目录

题目

标题和出处

标题:重新格式化电话号码

出处:1694. 重新格式化电话号码

难度

3 级

题目描述

要求

给你一个字符串形式的电话号码 number \texttt{number} number。 number \texttt{number} number 由数字、空格 ‘   ’ \texttt{` '} ‘ ’ 和破折号 ‘-’ \texttt{`-'} ‘-’ 组成。

请你按下述方式重新格式化电话号码。首先,删除所有的空格和破折号。其次,将数字从左到右每 3 \texttt{3} 3 个一组分块,直到剩下 4 \texttt{4} 4 个或更少数字。剩下的数字将按下述规定再分块:

  • 2 \texttt{2} 2 个数字:单个含 2 \texttt{2} 2 个数字的块。
  • 3 \texttt{3} 3 个数字:单个含 3 \texttt{3} 3 个数字的块。
  • 4 \texttt{4} 4 个数字:两个分别含 2 \texttt{2} 2 个数字的块。

最后用破折号将这些块连接起来。注意,重新格式化过程中不应该生成仅含 1 \texttt{1} 1 个数字的块,并且最多生成两个含 2 \texttt{2} 2 个数字的块。

返回格式化后的电话号码。

示例

示例 1:

输入: number   =   "1-23-45   6" \texttt{number = "1-23-45 6"} number = "1-23-45 6"
输出: "123-456" \texttt{"123-456"} "123-456"
解释:数字是 "123456" \texttt{"123456"} "123456"。
步骤 1 \texttt{1} 1:共有超过 4 \texttt{4} 4 个数字,所以先取 3 \texttt{3} 3 个数字分为一组。第 1 \texttt{1} 1 个块是 "123" \texttt{"123"} "123"。
步骤 2 \texttt{2} 2:剩下 3 \texttt{3} 3 个数字,将它们放入单个含 3 \texttt{3} 3 个数字的块。第 2 \texttt{2} 2 个块是 "456" \texttt{"456"} "456"。
连接这些块后得到 "123-456" \texttt{"123-456"} "123-456"。

示例 2:

输入: number   =   "123   4-567" \texttt{number = "123 4-567"} number = "123 4-567"
输出: "123-45-67" \texttt{"123-45-67"} "123-45-67"
解释:数字是 "1234567" \texttt{"1234567"} "1234567"。
步骤 1 \texttt{1} 1:共有超过 4 \texttt{4} 4 个数字,所以先取 3 \texttt{3} 3 个数字分为一组。第 1 \texttt{1} 1 个块是 "123" \texttt{"123"} "123"。
步骤 2 \texttt{2} 2:剩下 4 \texttt{4} 4 个数字,所以将它们分成两个含 2 \texttt{2} 2 个数字的块。这 2 \texttt{2} 2 块分别是 "45" \texttt{"45"} "45" 和 "67" \texttt{"67"} "67"。
连接这些块后得到 "123-45-67" \texttt{"123-45-67"} "123-45-67"。

示例 3:

输入: number   =   "123   4-5678" \texttt{number = "123 4-5678"} number = "123 4-5678"
输出: "123-456-78" \texttt{"123-456-78"} "123-456-78"
解释:数字是 "12345678" \texttt{"12345678"} "12345678"。
步骤 1 \texttt{1} 1:第 1 \texttt{1} 1 个块是 "123" \texttt{"123"} "123"。
步骤 2 \texttt{2} 2:第 2 \texttt{2} 2 个块是 "456" \texttt{"456"} "456"。
步骤 3 \texttt{3} 3:剩下 2 \texttt{2} 2 个数字,将它们放入单个含 2 \texttt{2} 2 个数字的块。第 3 \texttt{3} 3 个块是 "78" \texttt{"78"} "78"。
连接这些块后得到 "123-456-78" \texttt{"123-456-78"} "123-456-78"。

示例 4:

输入: number   =   "12" \texttt{number = "12"} number = "12"
输出: "12" \texttt{"12"} "12"

示例 5:

输入: number   =   "--17-5   229   35-39475   " \texttt{number = "--17-5 229 35-39475 "} number = "--17-5 229 35-39475 "
输出: "175-229-353-94-75" \texttt{"175-229-353-94-75"} "175-229-353-94-75"

数据范围

  • 2 ≤ number.length ≤ 100 \texttt{2} \le \texttt{number.length} \le \texttt{100} 2≤number.length≤100
  • number \texttt{number} number 由数字和字符 ‘-’ \texttt{`-'} ‘-’ 及 ‘   ’ \texttt{` '} ‘ ’ 组成
  • number \texttt{number} number 中至少含 2 \texttt{2} 2 个数字

解法

思路和算法

由于在格式化电话号码时,只考虑电话号码中的数字,因此只需要知道电话号码中的数字有多少个,即可知道应该如何格式化。遍历原始电话号码 number \textit{number} number,统计数字的个数。

得到数字的个数之后,即可按照如下步骤生成格式化的电话号码。

  1. 当剩余的数字大于 4 4 4 个时,总是将数字按照每 3 3 3 个一组分块,因此遍历电话号码并生成含 3 3 3 个数字的块,得到一个含 3 3 3 个数字的块之后,则添加一个破折号。由于该操作是在剩余的数字大于 4 4 4 个时进行的,因此每次添加破折号之后,一定还有剩余的数字,即格式化的电话号码不会以破折号结尾。

  2. 当剩余的数字不超过 4 4 4 个时,剩余的数字可能是 4 4 4 个、 3 3 3 个或 2 2 2 个。当剩余 4 4 4 个数字时,可以生成 2 2 2 个块,当剩余 3 3 3 个或 2 2 2 个数字时,只可以生成 1 1 1 个块。因此当剩余 4 4 4 个数字时,继续遍历电话号码,再处理出一个含 2 2 2 个数字的块,然后添加一个破折号,则剩下 2 2 2 个数字。

  3. 当剩余的数字为 3 3 3 个或 2 2 2 个时,剩余的数字只能生成 1 1 1 个块,因此遍历电话号码的剩余部分直到结束,将剩余的数字全部添加到最后一个块即可。

如果电话号码中的数字大于 4 4 4 个,步骤 1 必定会执行,然后执行步骤 2 和步骤 3,或者只执行步骤 3。具体为,当电话号码中的数字个数除以 3 3 3 的余数为 1 1 1 时,会执行步骤 2 和步骤 3,当电话号码中的数字个数除以 3 3 3 的余数不为 1 1 1 时,只会执行步骤 3。

如果电话号码中的数字等于 4 4 4 个,则只会执行步骤 2 和步骤 3。

如果电话号码中的数字等于 3 3 3 个或 2 2 2 个,则只会执行步骤 3。

代码

class Solution {
    public String reformatNumber(String number) {
        final int BLOCK_SIZE = 3, SMALL_BLOCK_SIZE = 2;
        int digits = 0;
        int length = number.length();
        for (int i = 0; i < length; i++) {
            char c = number.charAt(i);
            if (Character.isDigit(c)) {
                digits++;
            }
        }
        StringBuffer sb = new StringBuffer();
        int index = 0;
        while (digits > 4) {
            int curBlockSize = BLOCK_SIZE;
            while (curBlockSize > 0) {
                char c = number.charAt(index);
                if (Character.isDigit(c)) {
                    sb.append(c);
                    curBlockSize--;
                }
                index++;
            }
            digits -= BLOCK_SIZE;
            sb.append('-');
        }
        if (digits == 4) {
            int curBlockSize = SMALL_BLOCK_SIZE;
            while (curBlockSize > 0) {
                char c = number.charAt(index);
                if (Character.isDigit(c)) {
                    sb.append(c);
                    curBlockSize--;
                }
                index++;
            }
            digits -= SMALL_BLOCK_SIZE;
            sb.append('-');
        }
        while (index < length) {
            char c = number.charAt(index);
            if (Character.isDigit(c)) {
                sb.append(c);
            }
            index++;
        }
        return sb.toString();
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 number \textit{number} number 的长度。需要遍历字符串 number \textit{number} number 两次。

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 number \textit{number} number 的长度。需要额外创建一个长度为 O ( n ) O(n) O(n) 的 StringBuffer \texttt{StringBuffer} StringBuffer 或 StringBuilder \texttt{StringBuilder} StringBuilder 类型的对象用于存储格式化后的电话号码。由于 Java 中的 String \texttt{String} String 类型的对象不可变,因此空间复杂度至少为 O ( n ) O(n) O(n)。

标签:格式化,数字,texttt,number,456,123,电话号码,字符串
来源: https://blog.csdn.net/stormsunshine/article/details/120167348

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有