[LeetCode] 831. Masking Personal Information

Chobby·2026년 10월 20일

LeetCode

목록 보기
1163/1173

문제

개인정보 문자열 s가 주어진다. 이메일이거나 전화번호이며, 아래 규칙으로 마스킹한 결과를 반환한다.

이메일

  • 전체를 소문자로 바꾼다.
  • 로컬 파트(@ 앞)는 첫 글자와 마지막 글자만 남기고 그 사이를 *****(5개)로 바꾼다.

전화번호

  • 숫자만 추출한다. 뒤 10자리가 지역 번호, 그 앞이 국가 코드다.
  • 마지막 4자리만 남기고 모두 *로 마스킹한다.
  • 국가 코드가 있으면 + 뒤에 자릿수만큼 *를 붙여 맨 앞에 둔다.
숫자 자릿수국가 코드출력 형식
10없음***-***-1111
111자리+*-***-***-1111
122자리+**-***-***-1111
133자리+***-***-***-1111

접근

분기는 @ 포함 여부 하나면 충분하다.

  1. 이메일: @로 나누고 소문자화한 뒤, 로컬 파트의 첫 글자 + ***** + 마지막 글자를 조합한다.
  2. 전화번호: 정규식으로 숫자만 모은다. slice(-10)으로 지역 번호를 떼고, 남는 길이가 국가 코드 자릿수다. 블록을 배열로 만들고 -로 합친다.

코드

function maskPII(s: string): string {
  if (s.includes('@')) {
    const [name, domain] = s.split('@').map((str) => str.toLowerCase());
    return name[0] + '*****' + name.at(-1) + '@' + domain;
  }

  const digits = s.match(/\d/g)!.join('');
  const localNum = digits.slice(-10);
  const countryCodeLen = digits.length - 10;

  const result = ['***', '***', localNum.slice(-4)];
  const countryCode = (countryCodeLen ? '+' : '') + '*'.repeat(countryCodeLen);
  if (countryCode) result.unshift(countryCode);

  return result.join('-');
}

막혔던 지점

처음에는 국가 코드를 '+'.repeat(len) + '*'.repeat(len)으로 만들었다.

입력:   "86-(10)12345678"
내 출력: "++**-***-***-5678"
기대값:  "+**-***-***-5678"

+와 *가 같은 개수로 늘어난다고 착각했다. 문제 예시를 다시 보면 +는 항상 1개이고, *만 국가 코드 자릿수를 따라간다. 10자리일 때는 +도 없어야 하므로 countryCodeLen ? '+' : ''로 처리했다.

정리

  • 시간 복잡도 O(n), 공간 복잡도 O(n).
  • 전화번호는 "앞에서 국가 코드 자르기"가 아니라 "뒤에서 10자리 자르기"로 생각하면 포맷이 단순해진다.
  • s.match()는 null을 반환할 수 있어 TS strict 모드에서는 ! 또는 null 체크가 필요하다.
profile
내 지식을 공유할 수 있는 대담함

0개의 댓글