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

말하는 감자·2022년 6월 27일
1

Programmers Level 1

목록 보기
25/66
post-thumbnail

프로그래머스 Level 1

🔒 문자열 내 마음대로 정렬하기

📚 문제 설명

문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 ["sun", "bed", "car"]이고 n이 1이면 각 단어의 인덱스 1의 문자 "u", "e", "a"로 strings를 정렬합니다.


✅ 제한 조건

  • strings는 길이 1 이상, 50이하인 배열입니다.

  • strings의 원소는 소문자 알파벳으로 이루어져 있습니다.

  • strings의 원소는 길이 1 이상, 100이하인 문자열입니다.

  • 모든 strings의 원소의 길이는 n보다 큽니다.

  • 인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.


📖 입출력 예

stringssreturn
["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.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

class Solution {
    public String[] solution(String[] strings, int n) {
        String[] answer = new String[strings.length];
        
        HashMap<Integer, String> map = new HashMap<Integer, String>();
			
		for(int i=0; i<strings.length; i++) {
            map.put(i, strings[i].substring(n, n+1));
		}
        
        String[] str = new String[strings.length];
        
        for(int j=0; j<map.size(); j++) {
            str[j] = map.get(j);
        }
        
        Arrays.sort(str);

       for(int k=0; k<map.size(); k++) {
           List<Integer> keyList = new ArrayList<Integer>();
           
           for(Map.Entry<Integer, String> entry : map.entrySet()){
                if(entry.getValue().equals(str[k]) ){
                  keyList.add(entry.getKey());
                }
            }
           if(keyList.size() == 1) {
               answer[k] = strings[keyList.get(0)];
           } else {
               String[] s = new String[keyList.size()];
               for(int t=0; t<keyList.size(); t++) {
                    s[t] = strings[keyList.get(t)];
               }
               Arrays.sort(s);
               for(int t=0; t<s.length;t++) {
                   answer[k++] = s[t];
               }
               k--;
           }
       }
        
        return answer;
    }
}

... 와 감자 머리 터지는 줄 알았다!!🤯

코드가 너무 길고 장황해서 감자도 잘 정리할 자신이 없다...

테스트 케이스도 성공 못하다가 한번 통과되니 채점해도 통과더라!

어떻게 해야 1차적으로 n번째 문자로 정렬하고 2차적으로 단어 전체를 정렬할까 고민하다가 "map으로 index와 값을 같이 저장하면 되지 않을까?!"에서 이 고생길이 시작되었다.

HashMapmapstrings의 인덱스를 key로 가져오고 해당 인덱스에 저장된 문자열의 n번째 문자를 값으로 가져와 저장하였다.

strings["sun", "bed", "car"]이고 n1이라면
map{0=u, 1=e, 2=a}을 가진다.

그리고 n번째 문자들만 저장하는 문자열 배열 strArrays.sort()로 정렬하였다.

정렬 전 str : [u, e, a]
정렬 후 str : [a, e, u]

정렬한 str의 값을 map의 값과 비교하여 key를 찾아낸다. 이때 값이 중복되어 key가 여러개일 수 있으므로 ArrayList타입인 keyList로 받았다.

keyList의 크기가 1이라면 중복된 값이 없으므로 바로 해당 인덱스를 가진 strings의 값을 answer에 넣어주고 1 이상이라면 strings에서 같은 값(n번째 문자)을 가진 단어들을 가져와 오름차순으로 정렬한 후 answer에 차례대로 넣어주었다.

answer에 단어를 넣어줄 때 마다 인덱스를 증가하게 되었는데 마지막 삽입시엔 별도의 인덱스 증가가 필요하지 않으므로 k--를 해주었다.

📑 HashMap value로 key 찾기 참고 사이트


🔓 다른 사람의 코드

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;
    }
}

와... 헛웃음이 나올 정도로 똑똑한 코드다...

비교해야할 n번째 문자 뒤에 strings의 단어를 붙혀서 문자열 배열 arr을 만들고 정렬했다.

그렇다면 우선적으로 n번째 문자를 정렬할 것이고 중복일시엔 단어 자체를 정렬할 것이다.

그리고 answer에 단어를 삽입할 때에는 substring을 통해 뒤에 붙힌 strings의 단어만 삽입한다.

감자가 원하던 게 이런 거였어요ㅠㅠㅠㅠ 엉엉ㅠㅠㅠㅠㅠ


🙁 느낀 점

이걸 어떻게 풀어야하지...?? 😟

했던 문제를 별다른 조언없이 감자 혼자 해결했다는 것에 의미를 둬야지...

그런데 마음이 씁쓸해지는 것은 어쩔 수가 없다...ㅠ

profile
나는 말하는 감자다

0개의 댓글