달리기 경주

달리기 경주

얀에서는 매년 달리기 경주가 열립니다. 해설진들은 선수들이 자기 바로 앞의 선수를 추월할 때 추월한 선수의 이름을 부릅니다. 예를 들어 1등부터 3등까지 "mumu", "soe", "poe" 선수들이 순서대로 달리고 있을 때, 해설진이 "soe"선수를 불렀다면 2등인 "soe" 선수가 1등인 "mumu" 선수를 추월했다는 것입니다. 즉 "soe" 선수가 1등, "mumu" 선수가 2등으로 바뀝니다.

선수들의 이름이 1등부터 현재 등수 순서대로 담긴 문자열 배열 players와 해설진이 부른 이름을 담은 문자열 배열 callings가 매개변수로 주어질 때, 경주가 끝났을 때 선수들의 이름을 1등부터 등수 순서대로 배열에 담아 return 하는 solution 함수를 완성해주세요.

https://school.programmers.co.kr/learn/courses/30/lessons/178871


import java.util.*;

public class Main {
    public static void main(String[] args) {
        String[] players = {"mumu", "soe", "poe", "kai", "mine"};
        String[] callings = {"kai", "kai", "mine", "mine"};
        var reuslt = solution_upgrade(players, callings);
        System.out.println(Arrays.toString(reuslt));
    }

    public static String[] solution(String[] players, String[] callings) {
        for (String call : callings) {

            for (int i = 0; i < players.length; i++) {
                if (players[i].equals(call)) {
                    players[i] = players[i - 1];
                    players[i - 1] = call;
                    break;
                }
            }

        }

        return players;
    }

    public static String[] solution_upgrade(String[] players, String[] callings) {
        Player.init(players);
        var test = Player.allPlayerList;
        for (String player : callings) {
            Player.call(player);
        }

        var player = Player.firstPlayer;
        int i = 0;
        String[] result = new String[players.length];
        while (true) {
            System.out.println(player.name);
            result[i] = player.name;

            player = player.back;

            if (player == null) {
                break;
            }

            i++;

        }

        return result;
    }

}

class Player {
    static List<Player> allPlayerList = new ArrayList<>();
    static HashMap<String, Player> allPlayerMap = new HashMap<>();
    static Player firstPlayer;

    String name;
    Player front;
    Player back;

    public static void init(String[] players) {
        for (String player : players) {
            new Player(player);
        }
    }

    private Player(String name) {
        this.name = name;


        if (!allPlayerList.isEmpty()) {
            Player frontPlayer = allPlayerList.get(allPlayerList.size() - 1);
            this.front = frontPlayer;
            frontPlayer.back = this;
        } else {
            firstPlayer = this;
        }
        allPlayerMap.put(name, this);
        allPlayerList.add(this);
    }

    static void call(String playerName) {
        var allPlayer = allPlayerList;
        Player currentPlayer = allPlayerMap.get(playerName);
        Player frontPlayer = currentPlayer.front;

        if (frontPlayer.front == null) {
            firstPlayer = currentPlayer;
        }

        changePosition(currentPlayer, frontPlayer);
    }

    private static void changePosition(Player currentPlayer, Player frontPlayer) {
        Player frontFront = frontPlayer.front;
        Player currentBack = currentPlayer.back;

        if (frontFront != null) {
            frontFront.back = currentPlayer;
        }

        if (currentBack != null) {
            currentBack.front = frontPlayer;
        }
        currentPlayer.front = frontFront;
        currentPlayer.back = frontPlayer;
        frontPlayer.front = currentPlayer;
        frontPlayer.back = currentBack;
    }
}


처음 시도했던 solution 함수의 경우 배열 순회로 인한 시간초과가 발생하여

이후 LinkedList 와 비슷한 형식으로 개선하여 해결함 (solution_upgrade)