Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Stack
- 어려웠던 문제
- 후위 표기법
- python
- 에라토스테네스의 체
- 조합
- Dynamic Programming
- dfs
- 순열
- 완전탐색
- 동적계획법
- 규칙찾기
- 쿼드압축 후 개수세기
- 튜플
- 프로그래머스
- 2017 카카오 코드
- 알고리즘
- 최소공배수
- 점프와 순간이동
- 문자열
- 보이어무어
- HashSet
- 완전 탐색
- pandas
- 영문자 확인
- HashMap
- Java
- fragment identifier
- 메뉴리뉴얼
- 반복문
Archives
- Today
- Total
csmoon1010의 SW 블로그
[200424] 이분탐색(Binary Search) - 예산(level3) 본문
1. 문제이해
- budgets의 합이 M이하이면 그대로 배정
- M 초과이면 상한액을 지정해 상한액 이상인 budgets은 상한액으로 처리
2. 전략
① budgets를 오름차순으로 배열
② limitIndex 함수 : 합이 M보다 작은 값 중 최대값을 가지는 index 구하기(이진탐색 이용)
- M보다 작음 :
**마지막 원소(모든 요청 가능) --> 해당 mid 출력
그 다음 원소값은 M보다 큼 --> 해당 mid 출력
else limitIndex(budgets, M, mid+1, end)
- M보다 큼 :
**첫 번째 원소(모든 요청 불가) --> -1출력
limitIndex(budgets, M, start, mid-1)
③ answer 구하기
- 모든 요청 가능 : 마지막 원소 출력
- 모든 요청 불가능 : M / 원소개수
- else : mid원소 + (남은 합 배분한 값)
3. 참고사항
- 내 방법의 문제점 : 예외처리가 많고 이진탐색으로 원소를 찾은 후 추가계산 필요
- 더 나은 방법 :
이진탐색의 대상을 인덱스가 아닌 budgets값 자체로 한다!!(범위 : 0 ~ budgets[budgets.length-1]);
재귀함수 대신 start <= end일 때까지를 대상으로 한다.(이진탐색의 일반적인 방법)
4. 코드
import java.util.*;
class Solution {
static int sum = 0;
public int solution(int[] budgets, int M) {
int answer = 0;
Arrays.sort(budgets);
int index = limitIndex(budgets, M, 0, budgets.length-1);
if(index == budgets.length -1){ //모든 요청 가능
answer = budgets[index];
}
else if(index == -1){ //모든 요청 불가능
answer = M / (budgets.length);
}
else{
int remain = (M-sum) / (budgets.length-index-1);
answer = budgets[index] + remain;
}
return answer;
}
public int limitIndex(int[] budgets, int M, int start, int end){
int mid = (start + end) / 2;
int target = budgets[mid];
sum = 0;
for(int i = 0; i < budgets.length; i++){
if(i <= mid) sum += budgets[i];
else sum += target;
}
if(sum <= M){ //M보다 작음. 뒤에 있거나 범위 내
if(mid == budgets.length-1) return mid; //마지막 원소 - 모든 요청 가능
else{
int next = sum + (budgets[mid+1] - target) * (budgets.length-mid-1);
if(next > M) return mid;
else return limitIndex(budgets, M, mid+1, end); //M보다 큼
}
}
else{
if(mid == 0) return -1; //첫 원소 - 모든 요청 불가능
else return limitIndex(budgets, M, start, mid-1);
}
}
}
/*
import java.util.*;
class Solution
{
public int solution(int[] budgets, int M)
{
Arrays.sort(budgets);
int start = 0, end = budgets[budgets.length - 1];
while(start <= end)
{
int sum = 0;
int mid = (start + end) / 2;
for(int element : budgets)
sum = element > mid ? sum + mid : sum + element;
if(sum > M) end = mid - 1;
else
start = mid + 1;
}
return end;
}
}
*/
'Coding Test > 프로그래머스' 카테고리의 다른 글
[200425] 깊이/너비우선탐색(DFS, BFS) - 단어변환(level3) (0) | 2020.04.25 |
---|---|
[200425] 그래프 - 가장 먼 노드(level3) (0) | 2020.04.25 |
[200424] 동적계획법(Dynamic Programming) - 타일장식물(level3) (0) | 2020.04.24 |
[200424] 동적계획법(Dynamic Programming) - N으로 표현(level3) (0) | 2020.04.24 |
[200421] 탐욕법(Greedy) - 섬 연결하기(level3) (0) | 2020.04.24 |
Comments