문제
문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.
< 제한 조건 >
- strings는 길이 1 이상, 50이하인 배열입니다.
- strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
- strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
- 모든 strings의 원소의 길이는 n보다 큽니다.
- 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
- 출력 예시 -
정답 코드
< 내 정답 코드 >
class Solution {
public String[] solution(String[] strings, int n) {
Arrays.sort(strings, new Comparator<String>() { // Comparator 인터페이스 구현
@Override
public int compare(String str1, String str2) { // compare() 메서드 오버라이딩
if (str1.charAt(n) < str2.charAt(n)) { // 전달받은 인덱스의 요소를 비교함
return -1;
} else if (str1.charAt(n) > str2.charAt(n)) {
return 1;
} else { // 만약 비교 문자가 동일하다면, 해당 문자의 앞에서부터 다시 비교
for (int i = 0; i < str1.length(); i++) {
if (str1.charAt(i) < str2.charAt(i)) {
return -1;
} else if (str1.charAt(i) > str2.charAt(i)) {
return 1;
}
}
}
return 0;
}
});
return strings;
}
}
< 타인 답변 코드 1 >
class Solution {
public String[] solution(String[] strings, int n) {
Arrays.sort(strings, new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
if (str1.charAt(n) < str2.charAt(n)) {
return -1;
} else if (str1.charAt(n) > str2.charAt(n)) {
return 1;
} else {
return str1.compareTo(str2); // String의 compareTo() 메서드를 사용!
}
}
});
return strings;
}
}
< 타인 답변 코드 2 >
class Solution {
public String[] solution(String[] strings, int n) {
String[] answer = {};
ArrayList<String> arr = new ArrayList<>();
for (int i = 0; i < strings.length; i++) {
arr.add("" + strings[i].charAt(n) + strings[i]);
}
Collections.sort(arr);
answer = new String[arr.size()];
for (int i = 0; i < arr.size(); i++) {
answer[i] = arr.get(i).substring(1, arr.get(i).length());
}
return answer;
}
}
이것을 주의하자!
- 내가 푼 방법은 Arrays.sort( ) 메서드이다. 정렬하려는 대상이 String 문자열이고, 이미 String 문자열은 Comparable 인터페이스의 compareTo( ) 메서드를 오버라이딩 해서 기본 오름차순으로 설정되어 있다. 따라서 해당 문자열 배열을 단순히 Arrays.sort( ) 해버리면 맨 앞의 String 요소를 기준으로 오름차순한다.
해당 문제처럼 정렬 기준을 바꾸기 위해선 Arrays.sort( ) 메서드의 매개변수에 따로 비교 기준을 정의해줘야 한다. 이때 Comparator 인터페이스의 compare( ) 메서드를 구현해 준다. 전달 받은 인덱스 n 을 이용하여 charAt( ) 메서드로 두 단어를 비교하고 -1 , 1 을 반환한다.
만약에 두 문자가 동일하다면, 내부에 for 문을 넣고 해당 문자열의 첫 인덱스부터 하나씩 비교한다. 제한 조건의 "인덱스의 문자가 동일할 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다"를 충족시키기 위한 것이다.
- 타인 답변 코드 1을 보면 나와 동일한 알고리즘을 사용했다. 하지만 나보다 좋은 점이 '동일한 문자일 경우'일 때 있다. 나는 코드를 새롭게 만들었는 반면, 타인 답변 코드 1에선 String 객체가 이미 가지고 있는 compareTo( ) 메서드를 사용했다. 생각해보면 어짜피 맨 앞에서부터 사전 순으로 비교할 거니깐 compareTo( ) 메서드를 사용해도 괜찮다..!
- 타인 답변 코드 2는 발상의 전환이 놀랍다. 먼저 String 배열을 ArrayList<String>에 저장하는데 이때 비교하려는 단어를 단어 맨 앞에 붙인다. 그리곤 정렬을 한다. 이후 새로운 배열에 넣을 때 비교 대상으로 사용한 단어를 제외한다. 정렬이라고 해도 다양한 방법이 가능하다. 이런 창의적인 방법은 배워야겠다.
'코딩 테스트' 카테고리의 다른 글
[프로그래머스] (Lv.1) 나누어 떨어지는 숫자 배열 (0) | 2022.09.01 |
---|---|
[프로그래머스] (Lv.1) 두 정수 사이의 합 * (0) | 2022.09.01 |
[프로그래머스] (Lv.1) 문자열 내 p와 y의 개수 (0) | 2022.09.01 |
[프로그래머스] (Lv.1) 문자열 내림차순으로 배치하기 (1) | 2022.09.01 |
[프로그래머스] (Lv.1) 문자열 다루기 기본 (0) | 2022.09.01 |