# \[99클럽 코테 스터디 3일차 TIL] 프로그래머스 - 문자열 내 마음대로 정렬하기

## \[level 1] 문자열 내 마음대로 정렬하기 - 12915

[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/12915?language=java)

#### 성능 요약

메모리: 75 MB, 시간: 3.18 ms

#### 문제 설명

문자열로 구성된 리스트 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"] 입니다.

***

## 풀이 코드

```java
import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        Arrays.sort(strings);
        List<String> list = Arrays.asList(strings);
        list.sort((o1, o2) -> {
            if (o1.charAt(n) > o2.charAt(n)) return 1;
            else if (o1.charAt(n) < o2.charAt(n)) return -1;
            else return 0;
        });
        return list.toArray(new String[0]);
    }
} 
```

`Comparator` 인터페이스를 익명 객체로 구현하여 풀었다. `o1.charAt(n) == o2.charAt(n)` 조건일 경우, 원래는 `o1.compareTo(o2);` 로 반환했는데 생각해보니 입력 문자열을 먼저 정렬하고 0 을 반환하면 추가 연산도 없고 사전순으로 나올 것으로 생각했다.

### 개선하기

위의 코드는 아래와 같이 `comparingInt()` 함수로 더 줄일 수 있다.

```java
import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        Arrays.sort(strings);
        List<String> list = Arrays.asList(strings);
        list.sort(Comparator.comparingInt(o -> o.charAt(n)));
        return list.toArray(new String[0]);
    }
}
```

***

## 돌아보기

어떻게 풀어야 할지 감을 못 잡아서 권장 시간을 초과할 때까지 못 풀었고 `Comparator` 를 겨우 생각해내서 풀었다.

다른 분의 풀이에서 생각지도 못한 풀이 방법을 봐서 공유한다.

### 풀이 1

```java
import java.util.*;

class Solution {
    public String[] solution(String[] strings, int n) {
        String[] answer = new String[strings.length];
        List<String> list = new ArrayList<>();
        for (String string : strings) {
            list.add(string.charAt(n) + string);
        }
        list.sort(String::compareTo);
        for (int i = 0; i < list.size(); i++) {
            answer[i] = list.get(i).substring(1);
        }
        return answer;
    }
}
```

n 번째 문자를 맨 앞에 두고 정렬한 다음 첫번째 문자(n번째 문자)를 제외한 문자만 반환하는 로직이다. `substring()` 메소드를 이렇게 참신하게 이용할 수 있다는게 놀라웠다. 속도는 다른 풀이에 비해 느리다.

그리고 문제 풀이를 고민하면서 문자 타입의 유니코드 값을 이용할 수 있지 않을까 했는데 해당 개념을 활용한 풀이도 확인할 수 있었다.

### 풀이 2

```java
import java.util.*;

class Solution {
    public static String[] solution(String[] strings, int n) {
        String[] answer = new String[strings.length];
        int cnt = 0;

        Arrays.sort(strings);

        for(int i = 97; i < 123; i++) {
            for (String string : strings) {
                if (string.charAt(n) == (char) i) {
                    answer[cnt++] = string;
                }
            }
        }
        return answer;
    }
}
```

입력 문자열을 정렬하고 알파벳 순서대로 n 번째 문자가 동일할 경우, 반환할 배열에 순차적으로 할당하는 풀이 방법이다. 왜 이 생각을 못했는지 스스로 참 아쉽다. 속도가 가장 빠른 풀이였다.

### 다음에는

1. `Comparator` 에 대해 공부하기
2. 차분하게 생각하기

***

\#99클럽 #코딩테스트준비 #개발자취업 #항해99 #TIL


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devlee.gitbook.io/docs/study/99/99-3-til.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
