有一个从1到n的线性花园。在每个点都有一个喷泉。给定数组a [n]告知有关喷泉的信息,以使其范围为喷泉左侧的max(i-a [i],1)到喷泉右侧的min(i + a [i],n)。查找最低编号的喷泉需要激活,以便覆盖整个花园。 例如,如果n = 3并且a = {1,2,1},则第二个喷泉的范围为1到3。因此,仅需要一个喷泉。这里的喷泉在1到2的范围内 2处的喷泉的范围是1到3,3处的喷泉的范围是2到3 因此,只有喷泉2足以激活以覆盖整个花园。
答案 0 :(得分:0)
答案 1 :(得分:0)
我认为您正在寻找O(n)时间和O(n)空间之外的解决方案。
创建间隔数组以存储可以从当前索引覆盖的最右边的范围。
public int findMinActivatedFountain(int[] arr, int n) {
int[] interval = new int[n];
int count = 1;
// At each index we'll store the max right possible from this index.
for (int i = 1; i <= n; i++) {
int left = Math.max(i - arr[i - 1], 1);
int right = Math.min(i + arr[i - 1], n);
interval[left - 1] = right;
}
int right = interval[0];
int currMax = right;
for (int i = 1; i < n; i++) {
currMax = Math.max(currMax, interval[i]);
// If the last fountain can cover only this point, then update with next fountain.
if (i == right) {
count++;
right = currMax;
}
}
return count;
}
答案 2 :(得分:0)
rightLimit =0;
leftLimit = 0;
for(i=0; i<n; i++){
if(rightLimit> fountainArray[i].rightLimit){
if(leftLimit<= fountainArray[i].leftLimit){
fountainStack.pop();
//similarly check left limit of the new fountain on top
//keep popping elements till fountainArray[i].leftLimit is > leftLimit of
//fountain on top of stack
}
fountainStack.push(fountainArray[i]);
}
}
return fountainStack.length();
答案 3 :(得分:0)
遍历所有喷泉并构造数组跳转:
jumps [i] = {在i处其范围的左边界的所有喷泉的最大范围}
for (int i = 1; i <= n; i++){
l = max(1, i - arr[i-1])
r = min(n, i + arr[i-1])
jumps[l] = max(jumps[l], r - l);
}
然后在跳转数组上应用跳转游戏II(https://leetcode.com/problems/jump-game-ii/)。 这需要O(n)时间
答案 4 :(得分:0)
public static int find(int arr[], int n){
for (int i = 1; i <= n; i++){
int l = max(1, i - arr[i-1])
int r = min(n, i + arr[i-1])
jumps[l] = max(jumps[l], r - l);
}
int longest = jump(jumps);
if(arr.lenght == longest){
return 0;
}else{
return arr.length-longest-1;
}
}
// get the minimum jump to reach
public static int jump(int[] A) {
int sc = 0;
int e = 0;
int max = 0;
for(int i=0; i<A.length-1; i++) {
max = Math.max(max, i+A[i]);
if( i == e ) {
sc++;
e = max;
}
}
return sc;
}
答案 5 :(得分:0)
拉维的答案是正确的,但是其中有一个小错误
// At each index we'll store the max right possible from this index.
for (int i = 1; i <= n; i++) {
int left = Math.max(i - arr[i - 1], 1);
int right = Math.min(i + arr[i - 1], n);
interval[left - 1] = right;
}
此处应为interval[left-1] = max(interval[left-1],right)
,
我们应该以该点为起点存储所有范围的最大值。休息都没错。