重新格式化电话号码
难度:
标签:
题目描述
代码结果
运行时间: 24 ms, 内存: 0.0 MB
/*
* 思路:
* 1. 删除所有空格和破折号
* 2. 按照每3个数字分组,直到剩下4个或更少的数字
* 3. 如果剩下4个数字,将其分为两个含2个数字的块
* 4. 用破折号连接这些块
*/
import java.util.stream.Collectors;
public class Solution {
public String reformatNumber(String number) {
// Step 1: Remove all spaces and dashes
String cleaned = number.chars()
.filter(Character::isDigit)
.mapToObj(c -> String.valueOf((char) c))
.collect(Collectors.joining());
StringBuilder result = new StringBuilder();
int length = cleaned.length();
int index = 0;
// Step 2: Process the main part of the string
while (length > 4) {
result.append(cleaned, index, index + 3).append("-");
index += 3;
length -= 3;
}
// Step 3: Handle the remaining part of the string
if (length == 4) {
result.append(cleaned, index, index + 2).append("-")
.append(cleaned, index + 2, index + 4);
} else { // length is 2 or 3
result.append(cleaned, index, cleaned.length());
}
return result.toString();
}
}
解释
方法:
题解采用了正则表达式进行处理。首先,使用 re.sub('\D', '', number) 删除输入字符串中所有非数字的字符,包括空格和破折号。然后,使用另一个正则表达式 re.sub('(...?(?=..))', r'\1-', ...) 在适当的位置插入破折号。这个正则表达式分为两部分:'...?' 匹配2到3个数字;'(?=..)' 是正向前瞻,确保后面至少还有两个字符,这样可以保证不会在字符串末尾添加破折号。通过这种方式,能够正确地将字符串分组为每三个数字一组,直到最后剩余的数字按题目要求进行特殊处理。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
题解中的正则表达式`(...?(?=..))`是如何确保在数字剩余4个时正确分为两组的?
▷🦆
在使用正则表达式`re.sub('(...?(?=..))', r'\1-', digits_only)`时,这种方法是否会在某些特殊情况下引入非预期的破折号?例如,如果输入是'123456789',输出会是什么?
▷🦆
正则表达式中的前瞻`(?=..)`部分是如何工作的,它如何确保在适当的位置插入破折号而不会在字符串末尾添加破折号?
▷🦆
对于输入字符串长度极短(例如只含一个数字或两个数字)的情况,此算法如何处理?是否有必要添加特定的条件来处理这些情况?
▷