Closed icegosimperson closed 1 month ago
🤔 시간복잡도 고려사항
이분 탐색
혹은 매개 변수 탐색
💡 풀이 아이디어
매개 변수 탐색
가져가려는 나무의 길이보다 크면 true
// 해당 절단기의 높이로 자를 수 있는 나무의 총 길이를 구하는 결정함수
private static boolean isPossible(int param) {
long sum = 0;
for (int i = 0; i < n; i++)
sum += Math.max(0, arr[i] - param); // 음수가 될 수 없기 때문에 0으로 제한
// 자른 나무 길이의 총 합이 m 이상이면 가능
return sum >= m;
}
🤔 시간복잡도 고려사항
💡 풀이 아이디어
매개변수 탐색
while(s < e){
int m = (s+e)/2;
long sum = 0;
for(int height : arr){
if(height-m >0) sum += (height - m);// 나무 자르기
}
if(sum < M) e = m; // 잘린 길이가 M보다 작을 시 더 절단 높이 더 낮춤
else s = m+1;
}
while(s<-=e) -> UpperBound left, LowerBound -> right값 출력? UpperBound하는 경우 e-1해줘야함, lowerBound하는 경우 -1을 하지 않아도됨
🤔 시간복잡도 고려사항
💡 풀이 아이디어
구해야 하는 것(mid): 절단기에 설정할 수 있는 높이의 최댓값
결정문제 : 현재 설정한 높이값(mid)으로 M미터를 가져 갈 수 있는가 없는가
M의 크기를 제대로 안봐서 int로 설정해줘서 계속 틀렸습니다,,,, ㅎㅎㅎ 자바는 크기에 따라 정수 타입 설정 잘하기~
🤔 시간복잡도 고려사항
1 <= 나무의 수 <= 1,000,000
이기 떄문에 나무에 대해 2중 반복문을 진행하면 시간 초과 발생O(NlogN) = 19,931,568
이기 때문에 NlogN
방식으로 할 수 있는 방법 고려💡 풀이 아이디어
1 <= M <= 2,000,000,000
이기 때문에 int
형으로 선언한다면 연산 과정에서 overflow
가 발생할 수 있으므로 나무 길이와 관련된 변수는 long
으로 선언해주기11 22 33 44
이고, 길이 제한이 10
일 경우1 + 12 + 23 + 34 = 70
0 11 33 66 110
(110 - 0) - (길이 제한) * (자른 나무의 개수)
(누적합에서 마지막 idx 값 - 최초 잘리는 나무 직전 idx) - (길이제한) * 자른 나무의 개수
getUpperIdx(long[] arr, long target)
: 길이가 m
일 때, m
이 arr
배열에 있을 수 있는 가장 오른쪽 idx
반환long cutSum
: 잘린 나무들의 합계잘린 나무들의 합을 구할 때, 나무 배열에 대해 1,000번 선형탐색했을 때 시간 초과가 발생할 수 있다고 생각했는데, log_2(2_000_000_000)의 값이 약 31이어서 시간 초과가 발생하지 않네요!!! 제가 너무 복잡하게 생각했습니다!! ㅎㅎ
🤔 시간복잡도 고려사항
10^6
이분 탐색
💡 풀이 아이디어
높이 최대 값
: mid변수파라미터 서치
: 잘린 길이가 M보다 크거나 같은가findIdx()
: 절단기의 높이 height가 정해졌을때, 해당 높이로 자르기 시작할 나무 위치
findIdx()로 절단기에서 잘릴 나무부터 자르도록 했으나, 그냥
if tree > h
조건으로 for문 다 도는게 깔끔할 수도
canGet()
: 높이 h로 원하는 개수 C만큼 얻을 수 있는지 판단하는 결정함수while(left < rihgt)파였는데, 파라미터 서치할땐 while(left <= rihgt)로 두고 parm을 넣는게 안헷갈리는거 같네요ㅎ.ㅎ
🤔 시간복잡도 고려사항
10^6
O(logN)
으로 탐색 가능 / 완전탐색 불가💡 풀이 아이디어
left <= right
나무의 길이 M에 맞춰야 하기 때문에 left와 right가 겹쳐지는 구간의 mid 값이 높이의 최댓값이 됨