[Java] 자바 알고리즘, 문자열 내 마음대로 정렬하기, Programmers level
- 알고리즘 문제/[Java] 알고리즘
- 2019. 8. 31. 16:20
문자열 내 마음대로 정렬하기
문제 설명
문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다.
예를 들어 strings가 [sun, bed, car]이고 n이 1이면 각 단어의 인덱스 1의 문자 u, e, a로 strings를 정렬합니다.
제한 조건
- strings는 길이 1 이상, 50이하인 배열입니다.
- strings의 원소는 소문자 알파벳으로 이루어져 있습니다.
- strings의 원소는 길이 1 이상, 100이하인 문자열입니다.
- 모든 strings의 원소의 길이는 n보다 큽니다.
- 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.
입출력 예
strings | n | return |
[sun, bed, car] | 1 | [car, bed, sun] |
[abce, abcd, cdx] | 2 | [abcd, abce, cdx] |
입출력 예 설명
입출력 예 1
sun, bed, car의 1번째 인덱스 값은 각각 u, e, a 입니다. 이를 기준으로 strings를 정렬하면 [car, bed, sun] 입니다.
입출력 예 2
abce와 abcd, cdx의 2번째 인덱스 값은 c, c, x입니다. 따라서 정렬 후에는 cdx가 가장 뒤에 위치합니다.
abce와 abcd는 사전순으로 정렬하면 abcd가 우선하므로, 답은 [abcd, abce, cdx] 입니다.
나의 풀이
import java.util.*;
class Solution {
public String[] solution(String[] strings, int n) {
List<String> list = new ArrayList<String>();
for (String str : strings) {
list.add(str);
}
list.sort(new Comparator<String>() {
@Override
public int compare(String str1, String str2) {
return str1.charAt(n) - str2.charAt(n) == 0 ?
str1.compareTo(str2) : str1.charAt(n) - str2.charAt(n);
}
});
String[] answer = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
answer[i] = list.get(i);
}
return answer;
}
}
- 이런 문제는 수준급 알고리즘 경험자가 아니라면 순수배열보다는 Collection 객체들(List, Map, Set 등)의 라이브러리 기능을 이용하는 것이 저같은 초보자에게 더 적당할 것 같다고 생각하여. 배열의 요소들을 먼저 list 객체에 담았다.
List 컬렉션은 sort메소드를 이용하여 요소들을 정렬하는 라이브러리 메소드를 제공하고 있는데 까다로운 것이 Comparator 익명객체를 파라미터로 받아 compare 메소드를 오버라이딩 해주어야한다.
이전 글 https://sas-study.tistory.com/105 을 참조하여 해당 오버라이딩 메소드를 작성하였다. 기본적으로 미리 알아두면 좋을만한 기능이지만, 업무를 하다보면 사용할 일이 거의 없기 때문에 알고리즘을 쓸때 수시로 써야겠다고 생각했다.
return 문을 간단히 설명하자면 charAt은 char 형 값을 반환한다.(ASCII 코드값으로 떨어진다.) 그렇기 때문에 값비교가 가능하고 둘을 뺀 값이 0이라는 것은 같은 값이기 때문에 이경우는 문자열 비교 메소드인 compareTo 메소드를 사용하여 사전에서 빠른 문자열이 앞으로 오도록 처리하였다.
다른사람의 풀이
import java.util.*;
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;
}
}
- 프로그래머스의 다른사람 풀이를 가져와봤다. 생각만 했던 풀이방법이었는데 실제로 구현하는 코드를 보니 더 신기했다. 처음에는 이분의 알고리즘처럼 풀어보려고 했으나 자잘자잘한 변환과정이 너무 많은것 같아 성능이슈가 발생할 가능성이 많다고 생각했다. 왜냐하면 위의 알고리즘은 index를 가지고 있어야 하는데 그것을 자르던 어떻게하던 변환과정이 하나 더 추가되기 때문이었다. 레벨1정도의 문제에서는 굳이 중요하지는 않겠지만 좀더 좋은 성능을 내고자하는 욕심이 생긴것 같아서 뿌듯했다.
나의 다른 풀이
좀더 적은 코드로 효율적인 풀이방법이 떠올라서 풀어보았습니다.
import java.util.*;
class Solution {
public String[] solution(String[] strings, int n) {
Arrays.sort(strings, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
return s1.charAt(n) - s2.charAt(n) != 0
? s1.charAt(n) - s2.charAt(n)
: s1.compareTo(s2); // 두 문자중 사전순으로 빠른거.
}
});
return strings;
}
}
- n 번째의 인덱스 문자를 비교하고 0(같은경우) 인 경우는 compareTo 메소드를 이용하여 사전순으로 더 빠른 문자가 앞으로 오도록 정렬하도록 풀이를 더욱 간단하게 변경.
- 그리고 List로 굳이 변환하지 않고 바로 정렬함.
'알고리즘 문제 > [Java] 알고리즘' 카테고리의 다른 글
[Java] 자바 알고리즘, 쇠막대기 programmers 스택/큐 알고리즘 (1) | 2019.09.01 |
---|---|
[Java] 자바 알고리즘, 탑(TOP) 문제 프로그래머스 level2 (1) | 2019.08.31 |
[Java] 자바 알고리즘, 백준 2839번 "설탕 배달" (2) | 2019.05.05 |
[Java] 자바 알고리즘, 백준 알고리즘 문제풀이 "X보다 작은 수"(10871번) (0) | 2019.05.01 |
[Java] 자바 알고리즘, 백준 "세 수의 중간수 출력" 알고리즘 문제풀이 (0) | 2019.05.01 |