두 문자열이 주어지고 하나의 문자열을 이루는 문자의 순서를 바꾸어 재구성 할 수 있는지 묻는 문제였다. 재구성 할 수 있다는 것은 동일한 개수의 문자를 가지고 있는 것이다.

따라서 알파벳 각각이 몇 개 있는지 확인하였다.
확인하기 위해서 알파벳 개수 크기의 배열을 두 개 만든 후 각각의 문자에 따라 배열의 인덱스의 값을 올려주었다. 그리고 두 배열의 값들을 비교하면 결과를 확인할 수 있다.

public class Solution {  
    public boolean isAnagram(String s, String t) {  
        // 글자의 길이가 다르다면 다른 것, for 문의 s.length()로 두 문자열의 문자를 순회할 것이므로 체크  
        if(s.length() != t.length()) return false;  
  
        int[] word1 = new int[26];  
        int[] word2 = new int[26];  
        for(int i  = 0; i < s.length(); i++){  
            // 문자에 따라 인덱스의 값 증가, 'a'의 값 0번 인덱스로 하여 기준으로 한다.  
            word1[s.charAt(i) - 'a']++;  
            word2[t.charAt(i) - 'a']++;  
        }  
  
        for(int i = 0; i < word1.length; i++){  
            // 문자의 조합이 똑같은지 확인  
            if(word1[i] != word2[i]) return false;  
        }  
  
        return true;  
    }  
}

'Algolithm-Leetcode > Arrays & Hashing' 카테고리의 다른 글

Top K Frequent Elements  (0) 2026.08.23
Group Anagrams  (0) 2026.08.20
Contains Duplicate  (0) 2026.08.14
Two Sum  (0) 2026.07.21

코딩테스트 문제를 풀 다 시간 초과를 해결했던 경험에 대한 기록이다.

백준의 텀프로젝트 문제를 풀던 중(https://www.acmicpc.net/problem/9466)
내가 작성한 코드가 충분히 최적화 되었다고 생각했음에도 계속 시간 초과가 발생하였다.
관련하여 문제를 찾던 중 자바의 배열 생성이 시간 초과의 원인이 될 수 있다는 글을 발견하고, 해당 부분을 수정하여 통과하였다.


    private static int solution() throws IOException {
        int studentNum = Integer.parseInt(br.readLine());
        int[] team = new int[studentNum + 1];
        String[] input = br.readLine().split(" ");
        for(int i = 1; i <= studentNum; i++){
            team[i] = Integer.parseInt(input[i-1]);
        }

        checked = new boolean[studentNum + 1];
        result = studentNum;

        for(int i = 1; i <= studentNum; i++){
            if(checked[i]) continue;
            // 배열 초기화
            visited = new int[studentNum + 1];
            findTeam(team, i, 1, visited);
        }

        return result;
    }

    private static void findTeam(int[] team, int student, int seq, int[] visited){
        if(checked[student]) return;
        checked[student] = true;
        visited[student] = seq;

        int next = team[student];
        if(visited[next] != 0){
            result -= (seq - visited[next] + 1);
        }else{
            findTeam(team, next, seq + 1, visited);
        }
    }

 

시간 초과가 나던 시점의 내 코드는 위와 같았으며, 완전 탐색을 위하여 탐색 방문 배열을 new 명령어로 생성하고 있었다. 해당 배열의 크기는 최대 100001의 크기를 갖는 문제이다.

 

    private static int solution() throws IOException {
        int studentNum = Integer.parseInt(br.readLine());
        int[] team = new int[studentNum + 1];
        StringTokenizer st = new StringTokenizer(br.readLine());
        for(int i = 1; i <= studentNum; i++){
            team[i] = Integer.parseInt(st.nextToken());
        }

        checked = new boolean[studentNum + 1];
        int[] visited = new int[studentNum + 1];
        result = studentNum;
        for(int i = 1; i <= studentNum; i++){
            if(checked[i]) continue;
            findTeam(team, i, 0, visited);
        }

        return result;
    }

    private static void findTeam(int[] team, int student, int seq, int[] visited){
        if(checked[student]) return;
        seq++;
        checked[student] = true;
        visited[student] = seq;

        int next = team[student];
        if(visited[next] != 0){
            result -= (seq - visited[next] + 1);
        }else{
            findTeam(team, next, seq, visited);
        }

        // dfs 내부에서 사용후 값 원상복구
        visited[student] = 0;
    }

}

 

시간 초과를 해결한 코드는 위와 같다. dfs를 반복하기 이전에 생성한 배열의 값을 new 가 아닌 직접 초기화 하여 배열을 사용하였다. 참고한 글(https://okky.kr/questions/1450047)에 따르면 배열을 생성한다는 것은 새로운 객체의 메모리에 할당 받는 부분, java의 경우 해당 배열의 초기 값을 초기화하는 부분 등으로 인하여 런타임 실행 시간이 늘어날 수 있다고 한다. 단순한 코드의 차이였지만 객체 생성의 효율에 대해 고민할 수 있었다.

+ Recent posts