프로그래머스 - L0 한번만등장한문자
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();
}
}
ㅎ... 좀 더 오래 생각했으면 떠올렸을 것 같은 방법인데 참...