문제설명
입력 & 출력
나의 풀이
import java.util.*;
class Solution {
public int[] solution(String s) {
s = s.substring(2, s.length()- 2).replace("},{", "-");
String[] arr = s.split("-");
for(int i = 0 ; i < arr.length - 1 ; i++){ //길이에 따라 오름차순 정렬
for(int j = i+1 ; j < arr.length; j++){
if(arr[i].length() > arr[j].length()){
String tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
Set<Integer> set = new LinkedHashSet<>();
for(String n_tuple : arr){
String[] tuples = n_tuple.split(",");
for(String tuple : tuples){
set.add(Integer.parseInt(tuple));
}
}
int[] answer = new int[set.size()];
int idx = 0 ;
for(int num : set){
answer[idx++] = num;
}
return answer;
}
}
이번 문제는 특정 형식의 문자열 표현을 튜플로 변환하는 문제로, 주어진 문자열을 파싱 하여 특정 규칙에 따라 튜플을 구성하는 것이 목표입니다.
- 중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2)
- 원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2)
- 튜플의 원소 개수는 유한합니다.
- 원소의 개수가 n개이고, 중복되는 원소가 없는 튜플 (a1, a2, a3,..., an)이 주어질 때(단, a1, a2,..., an은 자연수), 이는 다음과 같이 집합 기호 '{', '}'를 이용해 표현할 수 있습니다.
- {{a1}, {a1, a2}, {a1, a2, a3}, {a1, a2, a3, a4}, ... {a1, a2, a3, a4,..., an}}
즉 각 튜플을 길이에 따라 오름차순으로 정렬해야하는 작업이 선행되어야 합니다.
먼저 입력값을 보면 "{{2}, {2,1}, {2,1,3}, {2,1,3,4}}"와 같이 되어있습니다. 따라서 각 튜플을 뽑아내기 위해서 숫자 문자만 골라내야 합니다.
입력값 s를 2번째부터 뒤에 2번째를 제외한 s로 분리하면 다음과 같고 "2}, {2,1}, {2,1,3}, {2,1,3,4" 사용하여 "}, {" ➡ "-"로 대체해 줍니다. 그리고 split() 메서드를 사용하여 그러면 [2, 2,1, 2,1,3, 2,1,3,4]와 같이 튜플의 숫자만 저장되게 됩니다.
그리고 문제의 핵심인 길이에 따라 오름차순으로 정렬을 해줘야 합니다.
이중 for문을 사용하여 길이를 비교한 후 긴 길이를 가진 튜플을 뒤로 밀어서 오름차순으로 정렬해 줍니다.
이제 각 튜플의 숫자들의 순서가 중요하고, 중복이 없어야 하기 때문에 LinkedHashSet을 사용했습니다.
그리고 향상된 for문을 사용하여 각 튜플을 접근해 주는데 각 튜플은 왼쪽 그림과 같이 ", "로 구분되어 있기 때문에 각 튜플을 split() 메서드를 사용하여 구분해 줍니다. 그리고 각 튜플을 정수형으로 캐스팅해서 LinkedHashSet에 add() 메서드를 사용하여 추가해 줍니다.
이제 집합형태의 LinkedHashSet을 배열로 변환하여 마무리하기 위해서 LinkedHashSet의 size()만큼 배열을 초기화해 주고, 해당 배열에 LinkedHashSet의 요소를 넣어주어 마무리해 줍니다.
refactoring ✅
import java.util.*;
class Solution {
public int[] solution(String s) {
//s = s.replaceAll("\\{","");
//String arr[] = s.substring(0,s.length() - 2).split("\\},");
s = s.substring(2, s.length()- 2).replace("},{", "-");
System.out.println(s);
// "-"를 기준으로 배열로 분리
String[] arr = s.split("-");
System.out.println(Arrays.toString(arr));
Arrays.sort(sArr, Comparator.comparingInt(String::length));
Set<Integer> set = new LinkedHashSet<>();
for(String n_tuple : arr){
System.out.println(n_tuple);
String[] tuples = n_tuple.split(",");
for(String tuple : tuples){
set.add(Integer.parseInt(tuple));
}
}
int[] answer = new int[set.size()];
int idx = 0 ;
for(int num : set){
answer[idx++] = num;
}
return answer;
}
}
전체적인 코드는 "나의 풀이"와 동일합니다. 다른 점은 길이에 따라 오름차순으로 정렬하는 부분을
Arrays.sort(sArr, Comparator.comparingInt(String::length));
위와 같이 작성한 것입니다.
Comparator 인터페이스와 람다 표현식:
- Comparator.comparingInt(String::length) : Comparator 인터페이스의 정적 메서드인 comparingInt()를 사용하여 문자열의 길이를 기준으로 비교하도록 지정합니다.
- String::length : 문자열의 길이를 반환하는 메서드 레퍼런스입니다. 즉, 문자열의 길이를 기준으로 정렬하게 됩니다.
- comparingInt() 메서드: int 값을 반환하는 함수를 인수로 받아 해당 값을 기준으로 정렬합니다.
참고 ❗
'Coding Test > 프로그래머스' 카테고리의 다른 글
[프로그래머스] Lv.2 기능개발 (큐 Queue, peek(), offer(), ArrayList, Java) (1) | 2024.06.15 |
---|---|
[프로그래머스] Lv.2 의상 (HashMap, getOrDefault, Java) (0) | 2024.06.15 |
[프로그래머스] Lv.1 다트게임 (StringBuilder, isDigit(), isLetter(),Java) (1) | 2024.06.14 |
[프로그래머스] Lv.1 소수 만들기 (브루트 포스 알고리즘, Java) (1) | 2024.06.14 |
[프로그래머스] Lv.2 n^2 배열 자르기 (2차원 배열 ➡️ 1차원 배열 변환 행열 접근 공식,Java) (1) | 2024.06.13 |