티스토리 뷰

반응형

■ 문제

원본 사이트: https://www.hackerrank.com/challenges/sherlock-and-valid-string/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=strings 

 

Sherlock and the Valid String | HackerRank

Remove some characters from the string such that the new string's characters have the same frequency.

www.hackerrank.com

 

난이도: Medium

최대 스코어: 35

 

● 문제 요약

  • 문자열 s가 주어짐
  • 한 개의 문자는 제거 가능
  • 모든 문자가 동일한 횟수로 나타날 경우, 'YES' return
  • 아닐 경우, 'NO' return

 

예시:

s = abc
  • a: 1, b: 1, c: 1

==> 'YES' return

 

s = abcc
  • a: 1, b: 1, c: 2
  • c를 하나 제거하면 모두 1개로 같아짐

==> 'YES' return

 

 

■ 문제 풀이

일단, 각 문자가 나오는 횟수를 counter 배열에 저장하고 counter 배열을 내림차순으로 정렬한 뒤, counter 값이 0보다 큰 경우만 필터링한다.
그리고 a[2] ~ a[length-1]의 값이 a[1]과 같으면 'YES' 아니면 'NO'를 return하려고 했다.
근데 이 방법은 예외 케이스가 많아서 잘못된 방법이다.

그래서 생각을 거듭한 결과, 'YES'가 되는 경우를 찾았다.

  1. 문자의 개수가 1개인 경우
  2. 정렬한 counter 값 중 [0]과 [1]의 값이 같은 경우:
    • 정렬한 counter 배열의 마지막 값([length-1])이 [0]과 같을 때  --> ex) counter=[3, 3, ..., 3]
    • 정렬한 counter 배열의 마지막 값([length-1])은 1이고, 마지막 바로 앞의 값([length-2])은 [0]과 같을 때  --> ex) counter=[3, 3, ..., 3, 1]
  3. 정렬한 counter 값 중 [0]과 [1]의 값이 다른 경우:
    • 정렬한 counter 배열의 마지막 값([length-1])이 [1]과 같을 때  --> ex) counter=[4, 3, ..., 3]

 

위의 경우를 제외한 나머지 경우는 모두 'NO'가 된다.
근데, 여기서 주의해야할 점은 정렬한 counter 값 중 [0]과 [1]의 값이 2 이상 차이가 날 경우도 'NO'가 된다는 점이다.
위의 3. 케이스에서 이 부분을 걸러주지 않으면 오답이 나온다.  --> ex) counter=[4, 2, ..., 2] // 숫자 두 개를 지워야함

 

● 완성 코드 - 35 Points (Max)

'use strict';

const fs = require('fs');

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', function(inputStdin) {
    inputString += inputStdin;
});

process.stdin.on('end', function() {
    inputString = inputString.split('\n');

    main();
});

function readLine() {
    return inputString[currentLine++];
}

/*
 * Complete the 'isValid' function below.
 *
 * The function is expected to return a STRING.
 * The function accepts STRING s as parameter.
 */

function isValid(s) {
    // Write your code here
    let counter = [];
    let del = 0;
    for(let i=0; i<26; i++){
        counter[i] = 0;
    }
    
    for(let i=0; i<s.length; i++){
        counter[s.charCodeAt(i)-97]++;
    }
    counter = counter.filter((v) => v > 0);
    counter.sort((a, b) => { return b - a; });
    // console.log('sorted counter=', counter);
    
    const len = counter.length;
    if(len < 2){
        return 'YES';
    }
    if(counter[0] === counter[1]){
        if(counter[len-1] === counter[0]){
            return 'YES';
        }
        if(counter[len-2] === counter[0] && counter[len-1] === 1){
            return 'YES';
        }
        return 'NO';
    }
    else{
        if(counter[0] - counter[1] > 1){
            return 'NO';
        }
        if(counter[len-1] === counter[1]){
            return 'YES';
        }
        return 'NO';
    }
}

function main() {
    const ws = fs.createWriteStream(process.env.OUTPUT_PATH);

    const s = readLine();

    const result = isValid(s);

    ws.write(result + '\n');

    ws.end();
}
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함