문제 설명
어느 공원 놀이터에는 시소가 하나 설치되어 있습니다. 이 시소는 중심으로부터2(m)
,3(m)
,4(m)
거리의 지점에 좌석이 하나씩 있습니다.
이 시소를 두 명이 마주 보고 탄다고 할 때, 시소가 평형인 상태에서 각각에 의해 시소에 걸리는 토크의 크기가 서로 상쇄되어 완전한 균형을 이룰 수 있다면 그 두 사람을 시소 짝꿍이라고 합니다. 즉, 탑승한 사람의 무게와 시소 축과 좌석 간의 거리의 곱이 양쪽 다 같다면 시소 짝꿍이라고 할 수 있습니다.
사람들의 몸무게 목록weights
이 주어질 때, 시소 짝꿍이 몇 쌍 존재하는지 구하여 return 하도록 solution 함수를 완성해주세요.
import java.util.*; class Solution { public long solution(int[] weights) { long answer = 0; Map<Long, Integer> weightMap = new HashMap<Long, Integer>(); for(int weight : weights){ Long weight_long = Long.valueOf(weight); if(weightMap.containsKey(weight_long)) weightMap.put(weight_long, weightMap.get(weight_long)+1); else weightMap.put(weight_long,1); } for(Long weight_long : weightMap.keySet()){ if(weightMap.containsKey(weight_long)) // 1 : 1 nC2 answer+= weightMap.get(weight_long)*(weightMap.get(weight_long)-1)/2; if(weightMap.containsKey(weight_long*2/3)) // 2m : 3m answer+= weightMap.get(weight_long)*weightMap.get(weight_long*2/3); if(weightMap.containsKey(weight_long/2)) // 2m : 4m answer+= weightMap.get(weight_long)*weightMap.get(weight_long/2); if(weightMap.containsKey(weight_long*3/4)) // 3m : 4m answer+= weightMap.get(weight_long)*weightMap.get(weight_long*3/4); } return answer; } }
- 짝꿍 쌍을 구하는 과정에서
answer
는long
형 이기에 문제가 없다고 판단하였는데,
Long += Integer * Integer
의 형태였어서 오버플로우 문제가 있었다.- 무게를 저장하는
Map
을<Long, Integer>
에서<Long, Long>
으로 변경하여 해결하였다.Map<Long, Long> weightMap = new HashMap<Long, Long>(); //<Long, Long>으로 변경 for(int weight : weights){ Long weight_long = Long.valueOf(weight); if(weightMap.containsKey(weight_long)) weightMap.put(weight_long, weightMap.get(weight_long)+1); else weightMap.put(weight_long,1L); }
- 아마도 테스트 12~15에서 오버플로우가 발생했나보다
- 하지만 여전히 테스트 4~11은 통과하지 못하고있다.
- 로직에 어떤 문제가 있나 고민(1시간정도 고민했다)해본 결과 나눗셈을 하는 과정에서 소수점을 고려하지 않는 문제점이 있었다.
- 무게를 저장하는
Map
을<Long, Long>
에서<Double, Long>
으로 변경하여 해결하였다.Map<Double, Long> weightMap = new HashMap<Double, Long>(); for(int weight : weights){ Double weight_long = Double.valueOf(weight); if(weightMap.containsKey(weight_long)) weightMap.put(weight_long, weightMap.get(weight_long)+1); else weightMap.put(weight_long,1L); }
이번 문제는 학창시절에 경우의 수 문제 푸는거를 떠올려서 경우의 수 문제를 풀듯이 접근하였다.
그런데 자료구조형을 선택하는 과정에서 소수점과 오버플로우를 고려하지 못해서 시간이 좀 걸렸다. 돌이켜 생각해보면 오버플로우와 소수점문제가 발생한다는 사실을 생각하지 못해서 발생한 문제였다.
알고리즘 문제를 많이 풀면서 경험을 많이 쌓아야 겠다.