Study with me/프로그래머스 L0 마스터하기

프로그래머스 - L0 한번만등장한문자

외계나무 2024. 4. 4. 00:29

프로그래머스 - level 0 한 번만 등장한 문자

1. 첫 번째 시도

StringBuilder를 찾다가 replace가 생각나서 이렇게 풀었다.

그리고 새로운 앎을 얻었지... str.replace(old, new); 메서드는 기존 문자열을 변환하는 게 아니라 새로운 문자열을 반환한다는 것... 사실 String이 불변값이기 때문에 당연한 일인데 놓치고 말았다.

Java Visualizer 통해서 이 구간이 안 되는 걸 발견하고 chatGPT에게 묻고서야 발견함... 

class Solution {
    public String solution(String s) {
        String answer = "";
        String standard = "";
        for(int i=0; i<s.length(); i++) {
            String k = s.substring(i, i+1);
            if(!standard.contains(k)) {
                standard+=k;
                answer+=k;
            } else {
                answer = answer.replace(k, "");
            }
        }
        return answer.chars()
                .sorted()
                .collect(StringBuilder::new,
                        StringBuilder::appendCodePoint,
                        StringBuilder::append)
                .toString();
    }
}

결국 성공은 했음. 하지만 String answer를 정렬하는 방법을 (여기서) 복붙했기 때문에... 다시 풀어보기로.

 

2. 두 번째 시도

char 배열로 바꾼 다음 정렬하고 다시 String으로 바꾸는 방식.

사실 이것도 한 번 헤맸다. 직전 문제와 정반대의 이슈였는데, Arrays.sort( 배열 );이 따로 값을 반환하지 않고 해당 배열을 정렬한다는 걸 깜박해서 그냥 한 줄로 하려다가 왜 안돼??? 했었음 ㅋㅋㅋㅋ

import java.util.Arrays;

class Solution {
    public String solution(String s) {
        String answer = "";
        String standard = "";
        for(int i=0; i<s.length(); i++) {
            String k = s.substring(i, i+1);
            if(!standard.contains(k)) {
                standard+=k;
                answer+=k;
            } else {
                answer = answer.replace(k, "");
            }
        }
        char[] ans = answer.toCharArray();
        Arrays.sort(ans);
        return new String(ans);
    }
}

여튼 char[] <-> String은 기억해두면 유용한 것 같음...

 

3. 흥미로운 타인의 풀이

a-z로 하나 만들어 두고 필요한 것만 남기면 정렬할 필요 없을 것 같다는 생각은 했는데, 어떻게 남길지 생각이 닿지 않아서 보류했던 방법. 그냥 그걸 토대로 새로 만들면 되는 거였는데... 누군가가 깔끔하게 풀었길래 가져와 봤다. 

길이 26의 char 배열의 인덱스 0-25를 a-z의 아스키코드 값인 97-122로 매칭해서 푸는 방법.

주어진 s에서 알파벳이 나오면 그 아스키 값 - 97 자리에 1을 더하고, 최종적으로 배열에서 원소의 값이 1인 인덱스만 골라 그 인덱스+97을 아스키 값으로 가지는 알파벳을 빈 문자열에 추가하면 된다. 여기서는 97 대신 'a'로 직관적이게 보여줌.

class Solution {
    public String solution(String s) {
        int[] alpha = new int[26];
        for(char c : s.toCharArray()){
            alpha[c - 'a']++;
        }

        StringBuilder answer = new StringBuilder();
        for(int i = 0; i < 26; i++){
            if(alpha[i] == 1){
                answer.append((char)(i + 'a'));
            }
        }
        return answer.toString();
    }
}

ㅎ... 좀 더 오래 생각했으면 떠올렸을 것 같은 방법인데 참...