본문 바로가기
  • Secret Notes
CodeGym/프로그래머스

[프로그래머스] 시소 짝꿍 | 파이썬

by MemoryIterator 2024. 6. 5.
반응형


문제설명

더보기

어느 공원 놀이터에는 시소가 하나 설치되어 있습니다. 시소는 중심으로부터 2(m), 3(m), 4(m) 거리의 지점에 좌석이 하나씩 있습니다.
시소를 명이 마주 보고 탄다고 , 시소가 평형인 상태에서 각각에 의해 시소에 걸리는 토크의 크기가 서로 상쇄되어 완전한 균형을 이룰 있다면 사람을 시소 짝꿍이라고 합니다. , 탑승한 사람의 무게와 시소 축과 좌석 간의 거리의 곱이 양쪽 같다면 시소 짝꿍이라고 있습니다.
사람들의 몸무게 목록 weights 주어질 , 시소 짝꿍이 존재하는지 구하여 return 하도록 solution 함수를 완성해주세요.

 

제한사항

더보기

2 ≤ weights의 길이 ≤ 100,000

100 ≤ weights[i] ≤ 1,000

  • 몸무게 단위는 N(뉴턴)으로 주어집니다.
  • 몸무게는 모두 정수입니다.

 

입출력 예


문제풀이

  • 이번 문제는 시간복잡도에 대해서 다시 한번 고려해 볼 수 있는 시간이었다. 우선 생각났던 풀이는 이중 for문을 통하여 weights의 원소를 중복없이 2개씩 짝을 지어주고 그 두 값의 비율이 시소의 거리와 같은지를 확인하는 것이었다. 하지만 제한 사항에서 weights의 길이의 최댓값이 100,000이기 때문에 이중 for문을 사용하게되면 시간복잡도 O(n^2)으로 10억회의 연산을 수행하기 때문에 무조건 시간초과가 발생한다. 따라서 weights리스트의 접근이 아니라 weights가 가지고있는 원소(weight)에 대하여 접근해야한다.(dictionary 사용이 필요하다.)
  • 따라서 defaultdict(참고 : https://dongdongfather.tistory.com/69)을 import하여 weights의 원소들을 dict에 key로 담아주고 해당 원소들의 갯수를 val로 담아준다. 그리고 각 key값을 확인하면서 key를 기준으로 생길 수 있는 시소 짝꿍을 조건으로 확인하면서 세어준다.
  • 우선 같은 무게를 가진 원소가 2개 이상이라면 nC2[(n * (n - 1)) // 2]의 조합으로 짝꿍이 생길 수 있으며 그리고 각 key에 대해서 시소의 좌석의 비율이 1 보다 큰 비율들을 확인하며 짝꿍의 수를 추가해준다. 이때 1보다 큰 비율만 확인하면 되는 이유는 모든 원소들을 전부 돌면서 확인을 해주기 때문에 결국 짝꿍을 중복해서 넣어주지 않기 위함이다. 이렇게 딕셔너리의 모든 원소들을 순회하면 요구하는 답을 얻은 수 있다.

코드 & 설명

from collections import defaultdict

def solution(weights):
    answer = 0
    le = len(weights)
    we_dict = defaultdict(int)
    for weight in weights:
        we_dict[weight] += 1
    for key, val in we_dict.items():
        if val > 1:
            answer += val * (val -1) // 2
        if key * 2 in we_dict:
            answer += val * we_dict[key * 2]
        if key * 3 % 2 == 0 and key * 3//2 in we_dict:
            answer += val * we_dict[key * 3//2]
        if key * 4 % 3 == 0 and key * 4//3 in we_dict:
            answer += val * we_dict[key * 4//3]
    return answer

 

 

728x90
반응형