Skip to content

Commit df3a08b

Browse files
authored
Merge pull request chipbk10#123 from chipbk10/BinarySearch
Binary search
2 parents 2f97660 + 819676c commit df3a08b

4 files changed

+140
-47
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package binarysearch;
2+
3+
public class Problem1011_CapacityToShipPackagesWithinDDays {
4+
5+
public int shipWithinDays(int[] weights, int D) {
6+
int lo = 0, hi = 0;
7+
for (int w: weights) {
8+
lo = Math.max(lo, w);
9+
hi += w;
10+
}
11+
while (lo <= hi) {
12+
int mid = lo + (hi-lo) / 2, need = 1, cur = 0;
13+
for (int w: weights) {
14+
if (cur + w > mid) {
15+
need += 1;
16+
cur = 0;
17+
}
18+
cur += w;
19+
}
20+
if (need <= D) hi = mid - 1;
21+
else lo = mid+1;
22+
}
23+
return lo;
24+
}
25+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package binarysearch;
2+
3+
public class Problem410_SplitArrayLargestSum {
4+
5+
public int splitArray(int[] A, int m) {
6+
int max = 0; long sum = 0;
7+
for (int a : A) {
8+
max = Math.max(max, a);
9+
sum += a;
10+
}
11+
12+
if (m == 1) return (int)sum;
13+
14+
long lo = max, hi = sum;
15+
while (lo <= hi) {
16+
long mid = (lo+hi)/2;
17+
if (isValid(A, m, mid)) hi = mid-1;
18+
else lo = mid+1;
19+
}
20+
21+
return (int)lo;
22+
}
23+
24+
private boolean isValid(int[] A, int m, long max) {
25+
int sum = 0, count = 1;
26+
for (int a : A) {
27+
sum += a;
28+
if (sum > max) {
29+
sum = a;
30+
count++;
31+
if (count > m) return false;
32+
}
33+
}
34+
return true;
35+
}
36+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package binarysearch;
2+
3+
public class Problem875_KokoEatingBananas {
4+
5+
public int minEatingSpeed(int[] piles, int H) {
6+
// min(K) : eat all piles & times <= H
7+
// [3,6,7,11]
8+
// K = 11 -> 4 hours
9+
// K = 8 -> 5 hours
10+
// K = 6 -> 1 + 1 + 2 + 2 = 6 hours
11+
// K = 5 -> 1 + 2 + 2 + 3 = 8 hours
12+
// K = 4 -> 1 + 2 + 2 + 3 = 8 hours
13+
// K = 3 -> 1 + 2 + 3 + 4 > 8 hours
14+
15+
// lo = 1, hi = max;
16+
// function(mid) <= H --> hi = mid-1
17+
// function(mid) > H --> lo = mid+1
18+
// return lo
19+
20+
int lo = 1, hi = 0;
21+
for (int pile: piles) hi = Math.max(hi, pile);
22+
23+
while (lo <= hi) {
24+
int mid = lo + (hi-lo)/2;
25+
if (timeToEatAll(piles, mid) <= H) hi = mid-1;
26+
else lo = mid+1;
27+
}
28+
return lo;
29+
}
30+
31+
private int timeToEatAll(int[] piles, int speed) {
32+
int res = 0;
33+
for (int pile : piles) {
34+
if (speed >= pile) res += 1;
35+
else {
36+
res += pile/speed;
37+
if (pile%speed != 0) res++;
38+
}
39+
}
40+
return res;
41+
}
42+
}

src/binarysearch/ReadMe.java

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,43 @@
22

33
public class ReadMe {
44

5-
/**
6-
* summary of 2 most frequently used binary search templates.
7-
* one is return index during the search:
8-
*
9-
* while lo <= hi:
10-
* mid = (lo+hi)/2
11-
* if nums[mid] == target:
12-
* return mid
13-
* if nums[mid] > target:
14-
* hi = mid-1
15-
* else:
16-
* lo = mid+1
17-
* return -1
18-
*
19-
* Another more frequently used binary search template is for searching lowest element
20-
* satisfy function(i) == True (the array should satisfy function(x) == False for 0 to i-1,
21-
* and function(x) == True for i to n-1, and it is up to the question to define the function,
22-
* like in the find peak element problem, function(x) can be nums[x] < nums[x+1] ),
23-
* there are 2 ways to write it:
24-
*
25-
* while lo <= hi:
26-
* mid = (lo+hi)/2
27-
* if function(mid):
28-
* hi = mid-1
29-
* else:
30-
* lo = mid+1
31-
* return lo
32-
*
33-
* or
34-
*
35-
* while lo < hi:
36-
* mid = (lo+hi)/2
37-
* if function(mid):
38-
* hi = mid
39-
* else:
40-
* lo = mid+1
41-
*
42-
* return lo ---> lowest element that satifies function(x)
43-
* return hi ---> highest element that not satifies function(x)
44-
*
45-
* No matter which one you use, just be careful about updating the hi and lo,
46-
* which could easily lead to infinite loop.
47-
* Some binary question is searching a floating number
48-
* and normally the question will give you a precision,
49-
* in which case you don't need to worry too much about the infinite loop
50-
* but your while condition will become something like "while lo+1e-7<hi"
51-
*
5+
/*
6+
|--x-----x------[v]vvvvvvvvvvvvvvvv|
7+
while (lo <= hi) {
8+
int mid = lo + (hi-lo)/2;
9+
if function(mid)
10+
hi = mid-1;
11+
else
12+
lo = mid+1;
13+
}
14+
return lo; ---> lowest element that satisfies function(x)
15+
16+
|vvvvvvvvvvvvv[v]-----x------x-------|
17+
while (lo <= hi) {
18+
int mid = lo + (hi-lo)/2;
19+
if function(mid)
20+
lo = mid+1;
21+
else
22+
hi = mid-1;
23+
}
24+
return hi; ---> highest element that satisfies function(x)
25+
26+
|----x----[v]----------x--------------|
27+
while (lo <= hi) {
28+
int mid = lo + (hi-lo)/2;
29+
if function(mid) == target
30+
return mid;
31+
if function(mid) < target
32+
lo = mid+1;
33+
else
34+
hi = mid-1;
35+
}
36+
return -1;
37+
38+
Note: function(x) is non-decreasing function
39+
*/
40+
41+
/*
5242
*
5343
* Collections.binarySearch
5444
* Array.binarySearch

0 commit comments

Comments
 (0)