시소 짝꿍_복습

하이솝·2026년 9월 22일

코테 · Hash

목록 보기
11/12

2026.09.22

문제 풀이

1차 실행 오류


52.9/100.0

실패 및 시간 초과 오류


import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

class Solution {
    public long solution(int[] weights) {
        long result = 0;
        Arrays.sort(weights); // 오름차순 정렬
        for (int i = 0; i < weights.length; i++) {
            for (int j = i + 1; j < weights.length; j++) {
                int w = weights[i];
                int w2 = weights[j];
                int a = w * 3 / 2;
                int b = w * 2;
                int c = w * 2 / 3;
                int d = w * 4 / 3;
                int e = w / 2;
                int f = w * 3 / 4;
                if (w == w2) {
                    result++;
                } else if (a == w2) {
                    result++;
                } else if (b == w2) {
                    result++;
                } else if (c == w2) {
                    result++;
                } else if (d == w2) {
                    result++;
                } else if (e == w2) {
                    result++;
                } else if (f == w2) {
                    result++;
                }
            }
        }
        return result;
    }
}

2차 실행 오류


17.6/100.0

실패


실패 원인 분석

같은 몸무게의 사람이 여러명 있을 때를 고려하지 않아 result++을 했고,

이후 map.put(a, map.get(a) - 1), result += entry.getValue()
라는 잘못된 계산으로 인해
같은 몸무게를 가진 사람들끼리 짝을 지을 때가 제대로 계산이 되지 않았다.


import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

class Solution {
    public long solution(int[] weights) {
        long result = 0;
        Arrays.sort(weights); // 오름차순 정렬
        
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < weights.length; i++) {
            map.put(weights[i], map.getOrDefault(weights[i], 0) + 1);
        }
        
        for (int i = 0; i < weights.length; i++) {
            int w = weights[i];
            int a = w * 3 / 2;
            int b = w * 2;
            int c = w * 2 / 3;
            int d = w * 4 / 3;
            int e = w * 1 / 2;
            int f = w * 3 / 4;
            
            if (map.containsKey(a) && w < a) {
                map.put(a, map.get(a) - 1);
                result++;
            } else if (map.containsKey(b) && w < b) {
                map.put(b, map.get(b) - 1);
                result++;
            } else if (map.containsKey(c) && w < c) {
                map.put(c, map.get(c) - 1);
                result++;
            } else if (map.containsKey(d) && w < d) {
                map.put(d, map.get(d) - 1);
                result++;
            } else if (map.containsKey(e) && w < e) {
                map.put(e, map.get(e) - 1);
                result++;
            } else if (map.containsKey(f) && w < f) {
                map.put(f, map.get(f) - 1);
                result++;
            }
        }
            for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                if (entry.getValue() >= 2) {
                    result += entry.getValue();
                } 
            }
        return result;
    }
}

3차 실행 오류


29.4/100.0

실패


실패 원인 분석

a, b, c 각 수에 대해 소숫점 반올림을 하는 경우를 고려하지 않아
[100, 133] 의 경우, 기댓값이 0이지만 결과가 1이 나온다.


import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

class Solution {
    public long solution(int[] weights) {
        long result = 0;
        Arrays.sort(weights); // 오름차순 정렬
        
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < weights.length; i++) {
            map.put(weights[i], map.getOrDefault(weights[i], 0) + 1);
        }
        
        for (int i = 0; i < weights.length; i++) {
            int w = weights[i];
            int a = w * 3 / 2;
            int b = w * 2;
            int c = w * 2 / 3;
            int d = w * 4 / 3;
            int e = w * 1 / 2;
            int f = w * 3 / 4;
            
            if (map.containsKey(a) && w < a) {
                result += map.get(a);
            } if (map.containsKey(b) && w < b) {
                result += map.get(b);
            } if (map.containsKey(c) && w < c) {
                result += map.get(c);
            } if (map.containsKey(d) && w < d) {
                result += map.get(d);
            } if (map.containsKey(e) && w < e) {
                result += map.get(e);
            } if (map.containsKey(f) && w < f) {
                result += map.get(f);
            }
        }
        
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            Integer n = entry.getValue();
            if (n >= 2) {
                result += (n * (n - 1)) / 2;
            } 
        }
        
        return result;
    }
}

4차 실행 오류


76.5/100.0

실패


실패 원인 분석

result += (n * (n - 1)) / 2; 해당 코드의
Integer 범위 오류가 발생한 것이 원인이다.


import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

class Solution {
    public long solution(int[] weights) {
        long result = 0;
        Arrays.sort(weights); // 오름차순 정렬
        
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < weights.length; i++) {
            map.put(weights[i], map.getOrDefault(weights[i], 0) + 1);
        }
        
        for (int i = 0; i < weights.length; i++) {
            int w = weights[i];
            int a = w * 3 / 2;
            int b = w * 2;
            int c = w * 4 / 3;

            if (w * 3 % 2 == 0 && map.containsKey(a)) {
                result += map.get(a);
            } if (map.containsKey(b)) {
                result += map.get(b);
            } if (w * 4 % 3 == 0 && map.containsKey(c)) {
                result += map.get(c);
            }
        }
        
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            Integer n = entry.getValue();
            if (n >= 2) {
                result += (n * (n - 1)) / 2;
            } 
        }
        
        return result;
    }
}

나의 코드


소요 시간: 1시간 29분
시간 복잡도: O(NlogN)O(N log N)


import java.util.Arrays;
import java.util.Map;
import java.util.HashMap;

class Solution {
    public long solution(int[] weights) {
        long result = 0;
        Arrays.sort(weights); // 오름차순 정렬
        
        Map<Integer, Long> map = new HashMap<>();
        for (int i = 0; i < weights.length; i++) {
            map.put(weights[i], map.getOrDefault(weights[i], 0L) + 1);
        }
        
        for (int i = 0; i < weights.length; i++) {
            int w = weights[i];
            int a = w * 3 / 2;
            int b = w * 2;
            int c = w * 4 / 3;

            if (w * 3 % 2 == 0 && map.containsKey(a)) {
                result += map.get(a);
            } if (map.containsKey(b)) {
                result += map.get(b);
            } if (w * 4 % 3 == 0 && map.containsKey(c)) {
                result += map.get(c);
            }
        }
        
        for (Map.Entry<Integer, Long> entry : map.entrySet()) {
            Long n = entry.getValue();
            if (n >= 2) {
                result += (n * (n - 1)) / 2;
            } 
        }
        
        return result;
    }
}

AI 코드


시간 복잡도: O(N)O(N)


코드 분석

전체적인 구조는 유사하지만,
존재하는 몸무게의 범위가 넓지 않으므로
배열의 인덱스를 몸무게로 하여 저장했다.

시간 복잡도의 경우 나의 코드에서 Arrays.sort(weights)를 제거하면
동일한 시간 복잡도를 갖게 된다.


class Solution {
    public long solution(int[] weights) {
        long answer = 0;
        long[] cnt = new long[2001];   // cnt[w] = 지금까지 나온 몸무게 w의 개수 (w*2 ≤ 2000)

        for (int w : weights) {
            answer += cnt[w];                              // 1:1
            if (w % 2 == 0)     answer += cnt[w / 2];      // 2:1
            if (w * 2 % 3 == 0) answer += cnt[w * 2 / 3];  // 3:2
            if (w * 3 % 4 == 0) answer += cnt[w * 3 / 4];  // 4:3
            answer += cnt[w * 2];                          // 1:2
            if (w * 3 % 2 == 0) answer += cnt[w * 3 / 2];  // 2:3
            if (w * 4 % 3 == 0) answer += cnt[w * 4 / 3];  // 3:4
            cnt[w]++;
        }
        return answer;
    }
}

문제 풀이 후기

Integer 의 범위 초과와 소숫점을 고려하지 못했다.
Integer와 Long을 명확하게 구분해서 사용하는 습관이 필요하다.

해당 문제는 실패했지만, 얻어가는 것이 명확해서 기분이 좋다.
이렇게 실패해도 항상 무언가를 명확하게 배워갔으면 좋겠다.

0개의 댓글