잉?

[프로그래머스] 문자열 내 마음대로 정렬하기 (JAVA 자바) 본문

알고리즘_Algorism/프로그래머스

[프로그래머스] 문자열 내 마음대로 정렬하기 (JAVA 자바)

Jye_647 2023. 7. 27. 23:43
문제설명

 

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


두 가지 방법으로 풀어봤다.

 

- 우선 사전적 순서로 정렬

- LinkedHashMap을 통해 key(문자열), Value(문자)를 put

- 정렬을 위해 리스트에 담고 뽑아온 문자 순으로 정렬

public String[] solution(String[] strings, int n) {
    Arrays.sort(strings); // 먼저 사전적 순서로 정렬

    // 중복 X, 순서 O LinkedHashMap사용
    Map<String, Character> map = new LinkedHashMap<>();
    for(String in : strings){
        map.put(in, in.charAt(n));
    }

    // n번째에 위치한 문자 순서대로 정렬을 해야하기에
    // list에 map값 전체 담기 => ketSet()
    List<String> list = new ArrayList<>(map.keySet());
    // 리스트 정렬을 사용
    // list에 있는 값들을 a, b변수에 차례로 넣고 비교(compareTo)
    Collections.sort(list, (a, b) -> map.get(a).compareTo(map.get(b)));

    // 리스트를 배열로 바꾸기
    String[] answer = list.toArray(new String[0]);

    return answer;
}

테스트 1 〉	통과 (1.16ms, 73MB)
테스트 2 〉	통과 (1.20ms, 74.6MB)
테스트 3 〉	통과 (1.33ms, 73.9MB)
테스트 4 〉	통과 (1.07ms, 76.5MB)
테스트 5 〉	통과 (1.08ms, 73.7MB)
테스트 6 〉	통과 (1.29ms, 73.1MB)
테스트 7 〉	통과 (1.37ms, 76.3MB)
테스트 8 〉	통과 (1.11ms, 67.8MB)
테스트 9 〉	통과 (1.03ms, 73.7MB)
테스트 10 〉	통과 (1.75ms, 74.8MB)
테스트 11 〉	통과 (2.02ms, 75.1MB)
테스트 12 〉	통과 (1.55ms, 75.6MB)

compareTo() 함수 ["문자열의 비교"  "숫자의 비교"]

기존값. compareTo(비교값) → 기존값과 비교값을 비교

 

숫자의 비교

 

기존값 < 비교값  -1

기존값 = 비교값   0

기존값 > 비교값   1

 

문자열 비교

기준값에 비교대상이 포함되어 있을 경우 서로의 문자열 길이의 차이값을 리턴해준다.

abcd - ab = 2

abcd - ""  = 4


 public String[] solution(String[] strings, int n) {
        String[] answer = new String[strings.length];

        Arrays.sort(strings); // 먼저 사전적 순서로 정렬

        // 중복 X, 순서 O LinkedHashMap사용
        HashMap<String, Character> map = new LinkedHashMap<>();
        for(String in : strings){
            map.put(in, in.charAt(n));
        }

        // Map 인터페이스의 내부 인터페이스(inner interface) 이다.
        // https://junecode.tistory.com/113
        List<Map.Entry<String, Character>> entryList = new LinkedList<>(map.entrySet());

        // 값을 비교하고 정렬 (첫번째 방법에서 사용한 compareTo와 같다.)
        entryList.sort(Map.Entry.comparingByValue());

        int i = 0;
        for(Map.Entry<String, Character> entry : entryList){
            answer[i++] = entry.getKey();
        }

        return answer;
    }
    
테스트 1 〉	통과 (2.44ms, 77.1MB)
테스트 2 〉	통과 (1.96ms, 78.8MB)
테스트 3 〉	통과 (3.67ms, 72.6MB)
테스트 4 〉	통과 (2.65ms, 77.9MB)
테스트 5 〉	통과 (1.85ms, 76.2MB)
테스트 6 〉	통과 (2.02ms, 74.4MB)
테스트 7 〉	통과 (2.74ms, 80.9MB)
테스트 8 〉	통과 (2.40ms, 71.2MB)
테스트 9 〉	통과 (1.96ms, 78.9MB)
테스트 10 〉	통과 (3.08ms, 69.2MB)
테스트 11 〉	통과 (2.06ms, 78.4MB)
테스트 12 〉	통과 (2.96ms, 85.2MB)

Map.entry를 처음 사용해 봤다. 

Map 인터페이스의 내부 인터페이스(inner interface)이고,맵에 저장되는 엔트리의 조작을 위한 메서드가 정의되어 있다.내부 메서드가 다양한데 그중 일부분을 가져왔다.

 

Object.getKey() Entry의 key 객체 반환
Object.getValue() Entry이 value 객체 반환
Comments