https://school.programmers.co.kr/learn/courses/30/lessons/42885
구명보트에 최대 두 명이 탈 수 있다.
구명보트의 무게 제한과 사람들의 몸무게 리스트가 주어졌을 때, 구조를 위해 필요한 최소 구명보트 갯수를 반환하라
def solution(people, limit):
people.sort()
cnt = 0
while people:
tmp = 0
tmp+=people.pop()
if people:
if tmp+people[-1]<=limit:
tmp+=people.pop()
elif tmp+people[0]<=limit:
tmp+=people.pop(0)
cnt+=1
return cnt
첫 시도는 이게 아니었지만... 뭐 문제를 잘 읽어야겠다고 다시 다짐한다. (구명보트에 탈 수 있는 최대 인원은 2명이다.)
난 무거운 사람을 많이 태워가면 좋은거지~ 라고 생각하고, 일단 먼저 가장 무거운 사람 태우고, 그 다음 무거운 사람이 탈 수 있으면 타고, 아니면 가장 가벼운 사람이 탈 수 있는 경우 태우려고 했는데! 효율성 측면에서 문제가 생긴다.
찾아보니 pop(0)을 하면 O(1)이 아닌 O(N)이어서 이 문제에선 list의 pop을 쓰면 통과가 어려운듯하다.
*아 그리고 while, if문 등에서 리스트 그 자체는 비어있으면 False, 아니면 True를 반환한다.
질문하기 를 보니, 효율성을 통과하기 위해선 투포인터 알고리즘을 써야한다길래 그게 뭐지 했는데 pop, remove와 같은 함수를 사용해 실제 리스트를 수정하지 않고 두 개의 점의 위치를 기록하며 처리하는 알고리즘 이라고 한다. 즉 이 문제에선 리스트를 정렬 후 min, max에 포인터를 두고 인덱스로 조건 충족 여부를 확인하는거다.
def solution(people, limit):
people.sort()
cnt = 0
left = 0
right = len(people)-1
while left<right:
if people[left]+people[right]<=limit:
left+=1
right-=1
cnt+=1
if left==right:
cnt+=1
return cnt
이 코드도 사실 마음에 들진 않는데.. 암튼 리스트를 직접 수정하지 않고 포인터를 활용하는 방법이다.
아니 근데 난 잘 모르겠다. 몸무게가 가장 많이 나가는 두 명이 같이 나가는 경우가 있다해도 이 코드가 맞나? 오 그렇긴 하지... 차피 2명 나가는 게 최대니까?
에휴 암튼 힌트를 많이 보고 푼 문제여서 아쉬움이 남지만 투 포인터라는 방법을 익혔다고 생각하자!
def solution(people, limit):
people.sort()
cnt = 0
left = 0
right = len(people)-1
while left<right:
if people[left]+people[right]<=limit:
left+=1
cnt+=1
right-=1
return len(people)-cnt
return을 전체 사람 수 - 두명이서 나간 보트 수
하면 좀 더 간단하게 쓸 수 있다.
한 보트에 최대 두명이 탑승 가능하다는 게 아주 큰 정보였다.
# deque를 이용한 방법
from collections import deque
def solution(people, limit):
people = deque(sorted(people))
cnt = 0
while people:
tmp = 0
tmp+=people.pop()
if people:
if tmp+people[-1]<=limit:
tmp+=people.pop()
elif tmp+people[0]<=limit:
tmp+=people.popleft() #pop(0)만 popleft()로 변경해줬다.
cnt+=1
return cnt