티스토리 뷰
문제
programmers.co.kr/learn/courses/30/lessons/64062
코딩테스트 연습 - 징검다리 건너기
[2, 4, 5, 3, 2, 1, 4, 2, 5, 1] 3 3
programmers.co.kr
문제 상황
- 징검다리 배열이 주어지고 한명이 건널 때마다 돌다리의 숫자가 1씩 감소한다. 0이 되면 더이상 감소하지않지만 한번에 건널수 있는 길이가 k로 정해져있어 최대로 건널 수 있는 사람 수를 구한다.
해결 전략
- 최초에는 배열을 순회하며 1씩 줄이고 사람 수를 1씩 증가시켰다. 즉, 한사람씩 관찰하였는데 문제가 사람 수는 무제한이고 돌다리는 최대 2억번까지 가능하므로 이러면 연산을 최소 2억번 해야한다.
- 범위가 2억번이므로 최소 O(NlogN) 이하의 속도에서 검색할 필요가 있다.
- 최대 건널 수 있는 사람 수는 stones의 최대값을 넘어설 수 없다. 그래서 0명과 최대값 사이에서 이진탐색하며 그 숫자의 사람이 건널 수 있는지를 확인한다. 즉, 탐색하는 내용이 사람 수가 된다.
코드
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
def check(stones,k,mid):
# 연속으로 0의 개수가 얼마인지 확인
cnt = 0
for stone in stones:
stone -= (mid-1)
if stone <= 0:
cnt += 1
if cnt == k:
return False
else:
cnt = 0
return True
def solution(stones, k):
start = 0
end = max(stones)
while True:
mid = (start+end)//2
# 만약 mid만큼의 사람수가 건널 수 있다고 하면
if check(stones, k, mid):
start = mid
else:
end = mid
if end-start <= 1:
return start if not check(stones,k,end) else end
print(solution([2, 4, 5, 3, 2, 1, 4, 2, 5, 1], 3))
# 정확도만 통과
# def check(stones, k):
# num = 0
# for i in range(len(stones)):
# if stones[i] == 0 :
# num += 1
# if num == k:
# return True
# else:
# num = 0
# return False
# def solution(stones, k):
# cnt = 0
# while True:
# # 0이 존재하는지 확인
# # 0*k가 stones에 존재하면 종료
# if check(stones,k,0,len(stones)-1):
# return cnt
# # 존재 안하면 한번씩 더 빼주기
# for i in range(len(stones)):
# if stones[i] != 0: stones[i] -= 1
# cnt += 1
|
cs |
해설
- 최초의 방법은 O(N)라고 생각하였지만 사람 수만큼 순회해야 하므로 정확히는 O(N*M)이 되어 효율성을 통과하지 못했다.
- 이진탐색을 생각했지만 그 적용을 0의 개수를 찾는데에서만 생각하다가 실패하였다.
새로 학습한 것 & 실수
- 문제를 풀 때에 한 번 생각이 고정되면 바꾸기가 어렵다. 문제의 경우 0의 개수를 탐색하는 것만 이진탐색으로 풀려다가 실패하였다.
- 탐색 자체는 선형 순회하면서 후보군을 이진 탐색하는 역발상을 할 필요가 있었다.
- 특히 마지막에 start를 반환한 이유는 start가 0이 아닐 경우 무조건 start만 반환하면 됬는데 start가 0이되면 end가 1일 때에 1이 반환이 안된다. 그래서 테스트 케이스 1번을 통과하지 못했지만 경계값을 기준으로 검사하여 오류를 발견했다.
'알고리즘 학습 > 프로그래머스' 카테고리의 다른 글
| 프로그래머스 - 셔틀버스 [Python] (0) | 2020.09.10 |
|---|---|
| 프로그래머스 - 보석 쇼핑 [Python] (0) | 2020.09.10 |
| 프로그래머스 - 추석 트래픽 [Python] (0) | 2020.09.08 |
| 프로그래머스 - 실패율 [Python] (0) | 2020.09.08 |
| 프로그래머스 - 디스크 컨트롤러 [Python] (0) | 2020.09.05 |
- Total
- Today
- Yesterday
- 병든 나이트#BOJ#탐욕법#Python
- 텀 프로젝트#백준알고리즘#Python
- Distinct#Codility#Python
- 날짜 계산#BOJ#완전탐색#Python
- 종이자르기#분할정복#BOJ#Python
- 미로 탐색#백준알고리즘#Python
- 순열사이클#BOJ#Python
- API#lazy#
- 반복수열#백준알고리즘#Python
- 랜선자르기#이분탐색#BOJ#Python
- 토마토#백준알고리즘#Python
- 파이썬알고리즘인터뷰#4장
- N으로 표현#DP#Programmers#Python
- django#slicing
- NumberofDiscIntersections#Codility#Sort#Python
- 암호코드#dp#BOJ#Python
- 리모컨#완전탐색#BOJ#Python
- filter#isalnum#lower
- Triangle#Sorting#Codility#Python
- Brackets#Stacks and Queues#Codility#Python
- 배열합치기#분할정복#BOJ#Python
- 터틀비치#리콘#xbox#controller
- 나무자르기#BOJ#이분탐색#Python
- 쿼드트리#BOJ#분할정복#Python
- PassingCars#Codility#Python
- django
- 공유기 설치#BOJ#이분탐색#Python
- 백준 알고리즘#BackTracking
- Swift#Tuples#Range
- 섬의개수#백준알고리즘#Python
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |