Medium
Bob is stuck in a dungeon and must break n locks, each requiring some amount of energy to break. The required energy for each lock is stored in an array called strength where strength[i] indicates the energy needed to break the ith lock.
To break a lock, Bob uses a sword with the following characteristics:
X by which the energy of the sword increases is 1.X.ith lock, the energy of the sword must reach at least strength[i].X increases by a given value K.Your task is to determine the minimum time in minutes required for Bob to break all n locks and escape the dungeon.
Return the minimum time required for Bob to break all n locks.
Example 1:
Input: strength = [3,4,1], K = 1
Output: 4
Explanation:
| Time | Energy | X | Action | Updated X |
|---|---|---|---|---|
| 0 | 0 | 1 | Nothing | 1 |
| 1 | 1 | 1 | Break 3rd Lock | 2 |
| 2 | 2 | 2 | Nothing | 2 |
| 3 | 4 | 2 | Break 2nd Lock | 3 |
| 4 | 3 | 3 | Break 1st Lock | 3 |
The locks cannot be broken in less than 4 minutes; thus, the answer is 4.
Example 2:
Input: strength = [2,5,4], K = 2
Output: 5
Explanation:
| Time | Energy | X | Action | Updated X |
|---|---|---|---|---|
| 0 | 0 | 1 | Nothing | 1 |
| 1 | 1 | 1 | Nothing | 1 |
| 2 | 2 | 1 | Break 1st Lock | 3 |
| 3 | 3 | 3 | Nothing | 3 |
| 4 | 6 | 3 | Break 2nd Lock | 5 |
| 5 | 5 | 5 | Break 3rd Lock | 7 |
The locks cannot be broken in less than 5 minutes; thus, the answer is 5.
Constraints:
n == strength.length1 <= n <= 81 <= K <= 101 <= strength[i] <= 106import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Solution {
public int findMinimumTime(List<Integer> strength, int k) {
List<Integer> strengthLocal = new ArrayList<>(strength);
Collections.sort(strengthLocal);
int res = strengthLocal.get(0);
strengthLocal.remove(0);
int x = 1;
while (!strengthLocal.isEmpty()) {
x += k;
int nextTime = (strengthLocal.get(0) - 1) / x + 1;
int canBreak = nextTime * x;
int indexRemove = findIndex(strengthLocal, canBreak);
if (strengthLocal.size() > 1) {
int nextTime1 = (strengthLocal.get(1) - 1) / x + 1;
int canBreak1 = nextTime1 * x;
int indexRemove1 = findIndex(strengthLocal, canBreak1);
if (nextTime1 + (strengthLocal.get(0) - 1) / (x + k)
< nextTime + (strengthLocal.get(1) - 1) / (x + k)) {
nextTime = nextTime1;
indexRemove = indexRemove1;
}
}
res += nextTime;
strengthLocal.remove(indexRemove);
}
return res;
}
private int findIndex(List<Integer> strength, int canBreak) {
int l = 0;
int r = strength.size() - 1;
int res = -1;
while (l <= r) {
int mid = (l + r) / 2;
if (strength.get(mid) <= canBreak) {
res = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
return res;
}
}