문제 설명 :
https://school.programmers.co.kr/learn/courses/30/lessons/64065
프로그래머스
SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프
programmers.co.kr
문제 요약 :
- 특정 튜플을 표현하는 집합이 담긴 문자열 s가 주어진다.
- s가 표현하는 튜플을 배열에 담아 반환
문제 풀이 시간 : 40분
문제 성공 여부 : 성공
접근 방법(비이상적인 버전) :
- 먼저 문제를 해결하는 방법은 매우 간단하다.
- {2}, {2,1}, {2,1,3} 이렇게 집합이 주어질 때, 가장 작은 집합{2}부터 다음으로 큰 집합에 처음으로 등장하는 수가 원본 튜플의 순서가 된다.
- 쉽게 말해 2가 제일 처음 나왔으니 원본 튜플에 2가 가장 먼저오고, 다음 {2,1}에 처음 오는 수가 1이니 원본 튜플은 [2,1]이 된다.
- 하지만 이 문제는 {2}, {2,1}, {2,1,3} 이런 숫자 집합을 어떻게 추출하느냐에 더 어려움을 겪었다.
import java.util.*;
class Solution {
public int[] solution(String s) {
List<String> list = new ArrayList<>();
s = s.substring(1,s.length()-1); // 일단 제일 처음과 끝 { } 삭제
Stack<Character> stack = new Stack<>();
String string = "";
int cnt = 0;
for(int i =0; i<s.length(); i++){
char c = s.charAt(i);
if(c == '{'){
stack.push(c);
}
else if(c == '}'){ // 집합 별로 list에 저장
stack.pop();
list.add(string);
string = "";
i++;
cnt++; // 집합의 개수
}
else{
string += c; // 2,1,3,... 을 string에 저장
}
}
// 결과적으로 list에 {2}, {2,1}, {2,1,3}, ... 이 저장된다
List<Integer>[] arr = new ArrayList[cnt]; // 각 인덱스 별로 하나의 집합에 해당하는 수 저장
for(int i = 0; i<arr.length; i++) arr[i] = new ArrayList<>();
int idx = 0;
for(String ss : list){
StringTokenizer st = new StringTokenizer(ss, ","); // 집합 내에 ","를 기준으로 숫자를 추출한다.
while(st.hasMoreTokens()){
int num = Integer.parseInt(st.nextToken()); // Integer로 변환시켜 arr에 추가한다
arr[idx].add(num);
}
idx++;
}
Arrays.sort(arr, (o1, o2) -> { // 집합의 크기가 작은 순(원소가 적은 순)으로 정렬한다.
return o1.size() - o2.size();
});
HashSet<Integer> hs = new HashSet<>();
int[] ans = new int[cnt];
idx = 0;
for(int i =0; i<cnt; i++){
for(int j =0; j<arr[i].size(); j++){
int num = arr[i].get(j);
if(!hs.contains(num)){ // 해시셋을 통해 존재하지 않는 수는 ans에 추가하고 hs에도 추가한다.
ans[idx++] = num;
hs.add(num);
}
}
}
return ans;
}
}
ㅋㅋㅋㅋㅋㅋ........................
풀면서도 느꼈는데 정리하면서 보니 너무너무너무 무식한 방법으로 문제를 해결한 것 같다..
시간을 재면서 풀었기에 조급한 마음에 코드를 쓴 탓도 있지만, String 메서드에 대한 무지함이 한몫한 것 같다..
접근 방법(이상적인 버전) :
- String 메서드 중 split이라는 것이 있었다. 원하는 문자열 단위로 String 배열에 분리할 수 있다.
- 제일 처음 {{와 }}를 빼고, },{ 단위로 숫자들을 분리하면 2 2,1,3 2,3 이렇게 집합을 쉽게 분리할 수 있다.
전체 코드(성공) :
import java.util.*;
class Solution {
public int[] solution(String s) {
s = s.substring(2,s.length()-2); // {{, }} 제거
String[] s_arr = s.split("\\},\\{"); // 이스케이프를 통해 },{를 기준으로 split한다.
Arrays.sort(s_arr, (o1,o2) -> { // 문자열 길이를 기준으로 정렬한다
return o1.length() - o2.length();
});
HashSet<String> hs = new HashSet<>();
int[] ans = new int[s_arr.length];
int idx = 0;
for(String ss: s_arr){
String[] temp = ss.split(","); // 한 집합에 대해 각 숫자들을 분리한다.
for(String num: temp){
if(!hs.contains(num)){ // 셋에 없을 경우 추가한다
ans[idx++] = Integer.parseInt(num);
hs.add(num);
}
}
}
return ans;
}
}
다른 고수분들의 코드에 비해서는 아직 지저분하지만, 내 코드 스타일이 반영된 만족스러운 코드인 것 같다.
'코테 > 프로그래머스' 카테고리의 다른 글
| [프로그래머스] 뒤에 있는 큰 수 찾기 (0) | 2025.05.20 |
|---|---|
| [프로그래머스] 섬 연결하기 - java (3) | 2025.05.14 |
| [프로그래머스] n^2 배열 자르기 - java (2) | 2025.05.06 |
| [프로그래머스] 연속 부분 수열 합의 개수 - java (2) | 2025.05.06 |
| [프로그래머스] 이진 변환 반복하기 - java (4) | 2025.04.08 |