0831. 隐藏个人信息【中等】
1. 📝 题目描述
给你一条个人信息字符串 s,可能表示一个 邮箱地址,也可能表示一串 电话号码。返回按如下规则 隐藏 个人信息后的结果:
电子邮件地址:
一个电子邮件地址由以下部分组成:
- 一个 名字,由大小写英文字母组成,后面跟着
- 一个
'@'字符,后面跟着 - 一个 域名,由大小写英文字母和一个位于中间的
'.'字符组成。'.'不会是域名的第一个或者最后一个字符。
要想隐藏电子邮件地址中的个人信息:
- 名字 和 域名 部分的大写英文字母应当转换成小写英文字母。
- 名字 中间的字母(即,除第一个和最后一个字母外)必须用 5 个
"*"替换。
电话号码:
一个电话号码应当按下述格式组成:
- 电话号码可以由 10-13 位数字组成
- 后 10 位构成 本地号码
- 前面剩下的 0-3 位,构成 国家代码
- 利用
{'+', '-', '(', ')', ' '}这些 分隔字符 按某种形式对上述数字进行分隔
要想隐藏电话号码中的个人信息:
- 移除所有 分隔字符
- 隐藏个人信息后的电话号码应该遵从这种格式:
"*-*-XXXX"如果国家代码为 0 位数字"+*-*-*-XXXX"如果国家代码为 1 位数字"+-*-*-XXXX"如果国家代码为 2 位数字"+*-*-*-XXXX"如果国家代码为 3 位数字
"XXXX"是最后 4 位 本地号码
示例 1:
txt
输入:s = "LeetCode@LeetCode.com"
输出:"l*e@leetcode.com"
解释:s 是一个电子邮件地址。
名字和域名都转换为小写,名字的中间用 5 个 * 替换。1
2
3
4
2
3
4
示例 2:
txt
输入:s = "AB@qq.com"
输出:"a*b@qq.com"
解释:s 是一个电子邮件地址。
名字和域名都转换为小写,名字的中间用 5 个 * 替换。
注意,尽管 "ab" 只有两个字符,但中间仍然必须有 5 个 *。1
2
3
4
5
2
3
4
5
示例 3:
txt
输入:s = "1(234)567-890"
输出:"*-*-7890"
解释:s 是一个电话号码。
共计 10 位数字,所以本地号码为 10 位数字,国家代码为 0 位数字。
因此,隐藏后的电话号码应该是 "*-*-7890"。1
2
3
4
5
2
3
4
5
提示:
s是一个 有效 的电子邮件或者电话号码- 如果
s是一个电子邮件:8 <= s.length <= 40s是由大小写英文字母,恰好一个'@'字符,以及'.'字符组成
- 如果
s是一个电话号码:10 <= s.length <= 20s是由数字、空格、字符'('、')'、'-'和'+'组成
2. 🎯 s.1 - 模拟
c
char* maskPII(char* s) {
char* res = (char*)malloc(100);
if (strchr(s, '@')) {
int n = strlen(s), at = 0;
for (int i = 0; i < n; i++) {
if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;
if (s[i] == '@') at = i;
}
sprintf(res, "%c*****%c%s", s[0], s[at - 1], s + at);
return res;
}
char digits[20]; int dLen = 0;
for (int i = 0; s[i]; i++) if (s[i] >= '0' && s[i] <= '9') digits[dLen++] = s[i];
digits[dLen] = '\0';
char local[13];
sprintf(local, "***-***-%.4s", digits + dLen - 4);
if (dLen == 10) { strcpy(res, local); return res; }
res[0] = '+';
for (int i = 0; i < dLen - 10; i++) res[1 + i] = '*';
res[1 + dLen - 10] = '-';
strcpy(res + 2 + dLen - 10, local);
return res;
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
js
/**
* @param {string} s
* @return {string}
*/
var maskPII = function (s) {
if (s.includes('@')) {
s = s.toLowerCase()
const [name, domain] = s.split('@')
return name[0] + '*****' + name[name.length - 1] + '@' + domain
}
const digits = s.replace(/\D/g, '')
const local = '***-***-' + digits.slice(-4)
if (digits.length === 10) return local
return '+' + '*'.repeat(digits.length - 10) + '-' + local
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
py
class Solution:
def maskPII(self, s: str) -> str:
if '@' in s:
s = s.lower()
name, domain = s.split('@')
return name[0] + '*****' + name[-1] + '@' + domain
digits = ''.join(c for c in s if c.isdigit())
local = '***-***-' + digits[-4:]
if len(digits) == 10:
return local
return '+' + '*' * (len(digits) - 10) + '-' + local1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 时间复杂度:
,其中 n 是字符串长度 - 空间复杂度:
算法思路:
- 邮箱:转小写,保留首尾字符,中间用 5 个星号替代
- 电话:提取数字,后 4 位明文,其余用星号并按格式加国际区号