본문 바로가기

Programming/데일리 알고리즘

[HackerRank] Sherlock and the Valid String (Javascript)

답을 찾기 위해서 고려해야 할 점

  • 인자값으로 받은 s의 길이가 1일 경우 YES를 반환한다. (코너 케이스)
  • 인자값으로 받은 s의 모든 알파벳의 갯수가 동일할 경우 YES를 반환한다. (코너 케이스)
    예) aaabbb => {3: aaa, bbb}
  • 인자값으로 받은 s의 모든 알파벳의 갯수는 2종류여야한다. 2종류 이상일 경우 무조건 NO이다.
    예) aaabbbcc => {2: cc}, {3: aaa, bbb}
    예) aaabbbcccceeeee => {3: aaa, bbb}, {4: cccc}, {5: eeeee} <= 무조건 NO이다
  • 인자값으로 받은 s의 모든 알파벳의 갯수가 2종류 일 경우, 갯수가 적거나 많은 것은 1개여야 한다.
    예) aaabbbcc => {2: cc}, {3: aaa, bbb} (갯수가 적은 그룹이 1개)
    예) aaabbcc => {2: bb, cc}, {3: aaa} (갯수가 많은 그룹이 1개)
  • 갯수가 많은 그룹이 1개일 경우, 갯수에서 1을 뻬면 적은 갯수와 값이 같아져야 한다.
    예) aaabbcc => {2: bb, cc}, {3: aaa} (3-1은 2이다.)
  • 갯수가 적은 그룹이 1개일 경우, 갯수에서 1을 빼면 0이 되어야 한다.
    예) abbbccc => {1: a}, {3: bbb, ccc} (1-1은 0이다. 즉, 소멸된다.)
function isValid(s) {
  let answer = "NO";

  // 인자값 s의 길이가 1인 경우 YES를 반환한다.
  if ( s.length === 1 ) {
    answer = "YES";
    return answer; 
  }

  let tempMap = new Map();
  for ( let i=0; i<s.length; i++ ) {
    if ( tempMap.has(s[i]) ) {
      tempMap.set(s[i], tempMap.get(s[i])+1);
    } else {
      tempMap.set(s[i], 1);
    }
  }

  let valueSet = new Set(); 
  let array = [];
  tempMap.forEach((value, key) => {
    valueSet.add(value);
    array.push(value);
  });
  
  if ( valueSet.size > 2 ) {
  // 값의 Range가 2보다 클 경우 NO를 반환한다.
    answer = "NO";
    return answer;
  } else if ( valueSet.size === 1 ) {
  // 값의 Range가 1일 경우 YES를 반환한다.
    answer = "YES";
    return answer;
  }

  let min = Math.min(...array);
  let max = Math.max(...array);
  let minCount = 0;
  let maxCount = 0;
  array.forEach((value) => {
    if ( max === value ) {
      maxCount++;
    }
    if ( min === value ) {
      minCount++;
    }
  });

  if ( minCount === 1 && min - 1 === 0 ) {
  // 갯수가 적은 그룹이 1개이고, 값에서 -1했을 때 0이면 YES를 반환한다.
    answer = "YES";
    return answer;
  }
  if ( maxCount === 1 && max - 1 === min ) {
  // 갯수가 많은 그룹이 1개이고, 값에서 -1했을 때 min과 같으면 YES를 반환한다.
    answer = "YES";
    return answer;
  }

  return answer;
}