题目

标题和出处

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

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

难度

3 级

题目描述

要求

给你一个字符串形式的电话号码 字符串题目:重新格式化电话号码 - 图1字符串题目:重新格式化电话号码 - 图2 由数字、空格 字符串题目:重新格式化电话号码 - 图3 和破折号 字符串题目:重新格式化电话号码 - 图4 组成。

请你按下述方式重新格式化电话号码。首先,删除所有的空格和破折号。其次,将数字从左到右字符串题目:重新格式化电话号码 - 图5 个一组分块,直到剩下 字符串题目:重新格式化电话号码 - 图6 个或更少数字。剩下的数字将按下述规定再分块:

  • 字符串题目:重新格式化电话号码 - 图7 个数字:单个含 字符串题目:重新格式化电话号码 - 图8 个数字的块。
  • 字符串题目:重新格式化电话号码 - 图9 个数字:单个含 字符串题目:重新格式化电话号码 - 图10 个数字的块。
  • 字符串题目:重新格式化电话号码 - 图11 个数字:两个分别含 字符串题目:重新格式化电话号码 - 图12 个数字的块。

最后用破折号将这些块连接起来。注意,重新格式化过程中不应该生成仅含 字符串题目:重新格式化电话号码 - 图13 个数字的块,并且最多生成两个含 字符串题目:重新格式化电话号码 - 图14 个数字的块。

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

示例

示例 1:

输入:字符串题目:重新格式化电话号码 - 图15
输出:字符串题目:重新格式化电话号码 - 图16
解释:数字是 字符串题目:重新格式化电话号码 - 图17
步骤 字符串题目:重新格式化电话号码 - 图18:共有超过 字符串题目:重新格式化电话号码 - 图19 个数字,所以先取 字符串题目:重新格式化电话号码 - 图20 个数字分为一组。第 字符串题目:重新格式化电话号码 - 图21 个块是 字符串题目:重新格式化电话号码 - 图22
步骤 字符串题目:重新格式化电话号码 - 图23:剩下 字符串题目:重新格式化电话号码 - 图24 个数字,将它们放入单个含 字符串题目:重新格式化电话号码 - 图25 个数字的块。第 字符串题目:重新格式化电话号码 - 图26 个块是 字符串题目:重新格式化电话号码 - 图27
连接这些块后得到 字符串题目:重新格式化电话号码 - 图28

示例 2:

输入:字符串题目:重新格式化电话号码 - 图29
输出:字符串题目:重新格式化电话号码 - 图30
解释:数字是 字符串题目:重新格式化电话号码 - 图31
步骤 字符串题目:重新格式化电话号码 - 图32:共有超过 字符串题目:重新格式化电话号码 - 图33 个数字,所以先取 字符串题目:重新格式化电话号码 - 图34 个数字分为一组。第 字符串题目:重新格式化电话号码 - 图35 个块是 字符串题目:重新格式化电话号码 - 图36
步骤 字符串题目:重新格式化电话号码 - 图37:剩下 字符串题目:重新格式化电话号码 - 图38 个数字,所以将它们分成两个含 字符串题目:重新格式化电话号码 - 图39 个数字的块。这 字符串题目:重新格式化电话号码 - 图40 块分别是 字符串题目:重新格式化电话号码 - 图41字符串题目:重新格式化电话号码 - 图42
连接这些块后得到 字符串题目:重新格式化电话号码 - 图43

示例 3:

输入:字符串题目:重新格式化电话号码 - 图44
输出:字符串题目:重新格式化电话号码 - 图45
解释:数字是 字符串题目:重新格式化电话号码 - 图46
步骤 字符串题目:重新格式化电话号码 - 图47:第 字符串题目:重新格式化电话号码 - 图48 个块是 字符串题目:重新格式化电话号码 - 图49
步骤 字符串题目:重新格式化电话号码 - 图50:第 字符串题目:重新格式化电话号码 - 图51 个块是 字符串题目:重新格式化电话号码 - 图52
步骤 字符串题目:重新格式化电话号码 - 图53:剩下 字符串题目:重新格式化电话号码 - 图54 个数字,将它们放入单个含 字符串题目:重新格式化电话号码 - 图55 个数字的块。第 字符串题目:重新格式化电话号码 - 图56 个块是 字符串题目:重新格式化电话号码 - 图57
连接这些块后得到 字符串题目:重新格式化电话号码 - 图58

示例 4:

输入:字符串题目:重新格式化电话号码 - 图59
输出:字符串题目:重新格式化电话号码 - 图60

示例 5:

输入:字符串题目:重新格式化电话号码 - 图61
输出:字符串题目:重新格式化电话号码 - 图62

数据范围

  • 字符串题目:重新格式化电话号码 - 图63
  • 字符串题目:重新格式化电话号码 - 图64 由数字和字符 字符串题目:重新格式化电话号码 - 图65字符串题目:重新格式化电话号码 - 图66 组成
  • 字符串题目:重新格式化电话号码 - 图67 中至少含 字符串题目:重新格式化电话号码 - 图68 个数字

解法

思路和算法

由于在格式化电话号码时,只考虑电话号码中的数字,因此只需要知道电话号码中的数字有多少个,即可知道应该如何格式化。遍历原始电话号码 字符串题目:重新格式化电话号码 - 图69,统计数字的个数。

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

  1. 当剩余的数字大于 字符串题目:重新格式化电话号码 - 图70 个时,总是将数字按照每 字符串题目:重新格式化电话号码 - 图71 个一组分块,因此遍历电话号码并生成含 字符串题目:重新格式化电话号码 - 图72 个数字的块,得到一个含 字符串题目:重新格式化电话号码 - 图73 个数字的块之后,则添加一个破折号。由于该操作是在剩余的数字大于 字符串题目:重新格式化电话号码 - 图74 个时进行的,因此每次添加破折号之后,一定还有剩余的数字,即格式化的电话号码不会以破折号结尾。
  2. 当剩余的数字不超过 字符串题目:重新格式化电话号码 - 图75 个时,剩余的数字可能是 字符串题目:重新格式化电话号码 - 图76 个、字符串题目:重新格式化电话号码 - 图77 个或 字符串题目:重新格式化电话号码 - 图78 个。当剩余 字符串题目:重新格式化电话号码 - 图79 个数字时,可以生成 字符串题目:重新格式化电话号码 - 图80 个块,当剩余 字符串题目:重新格式化电话号码 - 图81 个或 字符串题目:重新格式化电话号码 - 图82 个数字时,只可以生成 字符串题目:重新格式化电话号码 - 图83 个块。因此当剩余 字符串题目:重新格式化电话号码 - 图84 个数字时,继续遍历电话号码,再处理出一个含 字符串题目:重新格式化电话号码 - 图85 个数字的块,然后添加一个破折号,则剩下 字符串题目:重新格式化电话号码 - 图86 个数字。
  3. 当剩余的数字为 字符串题目:重新格式化电话号码 - 图87 个或 字符串题目:重新格式化电话号码 - 图88 个时,剩余的数字只能生成 字符串题目:重新格式化电话号码 - 图89 个块,因此遍历电话号码的剩余部分直到结束,将剩余的数字全部添加到最后一个块即可。

如果电话号码中的数字大于 字符串题目:重新格式化电话号码 - 图90 个,步骤 1 必定会执行,然后执行步骤 2 和步骤 3,或者只执行步骤 3。具体为,当电话号码中的数字个数除以 字符串题目:重新格式化电话号码 - 图91 的余数为 字符串题目:重新格式化电话号码 - 图92 时,会执行步骤 2 和步骤 3,当电话号码中的数字个数除以 字符串题目:重新格式化电话号码 - 图93 的余数不为 字符串题目:重新格式化电话号码 - 图94 时,只会执行步骤 3。

如果电话号码中的数字等于 字符串题目:重新格式化电话号码 - 图95 个,则只会执行步骤 2 和步骤 3。

如果电话号码中的数字等于 字符串题目:重新格式化电话号码 - 图96 个或 字符串题目:重新格式化电话号码 - 图97 个,则只会执行步骤 3。

代码

  1. class Solution {
  2. public String reformatNumber(String number) {
  3. final int BLOCK_SIZE = 3, SMALL_BLOCK_SIZE = 2;
  4. int digits = 0;
  5. int length = number.length();
  6. for (int i = 0; i < length; i++) {
  7. char c = number.charAt(i);
  8. if (Character.isDigit(c)) {
  9. digits++;
  10. }
  11. }
  12. StringBuffer sb = new StringBuffer();
  13. int index = 0;
  14. while (digits > 4) {
  15. int curBlockSize = BLOCK_SIZE;
  16. while (curBlockSize > 0) {
  17. char c = number.charAt(index);
  18. if (Character.isDigit(c)) {
  19. sb.append(c);
  20. curBlockSize--;
  21. }
  22. index++;
  23. }
  24. digits -= BLOCK_SIZE;
  25. sb.append('-');
  26. }
  27. if (digits == 4) {
  28. int curBlockSize = SMALL_BLOCK_SIZE;
  29. while (curBlockSize > 0) {
  30. char c = number.charAt(index);
  31. if (Character.isDigit(c)) {
  32. sb.append(c);
  33. curBlockSize--;
  34. }
  35. index++;
  36. }
  37. digits -= SMALL_BLOCK_SIZE;
  38. sb.append('-');
  39. }
  40. while (index < length) {
  41. char c = number.charAt(index);
  42. if (Character.isDigit(c)) {
  43. sb.append(c);
  44. }
  45. index++;
  46. }
  47. return sb.toString();
  48. }
  49. }

复杂度分析

  • 时间复杂度:字符串题目:重新格式化电话号码 - 图98#card=math&code=O%28n%29&id=xs65C),其中 字符串题目:重新格式化电话号码 - 图99 是字符串 字符串题目:重新格式化电话号码 - 图100 的长度。需要遍历字符串 字符串题目:重新格式化电话号码 - 图101 两次。
  • 空间复杂度:字符串题目:重新格式化电话号码 - 图102#card=math&code=O%28n%29&id=v2ymV),其中 字符串题目:重新格式化电话号码 - 图103 是字符串 字符串题目:重新格式化电话号码 - 图104 的长度。需要额外创建一个长度为 字符串题目:重新格式化电话号码 - 图105#card=math&code=O%28n%29&id=rmlAA) 的 字符串题目:重新格式化电话号码 - 图106字符串题目:重新格式化电话号码 - 图107 类型的对象用于存储格式化后的电话号码。由于 Java 中的 字符串题目:重新格式化电话号码 - 图108 类型的对象不可变,因此空间复杂度至少为 字符串题目:重新格式化电话号码 - 图109#card=math&code=O%28n%29&id=sRLNc)。