Arrays 找到所需喷泉的最小数量

Arrays 找到所需喷泉的最小数量,arrays,Arrays,从1到n有一个线性花园。每一处都有一个喷泉。给定数组a[n]告诉有关喷泉的信息,其范围是喷泉左侧的max(i-a[i],1)到喷泉右侧的min(i+a[i],n)。找到需要激活的喷泉的最小数量,以覆盖整个花园。 e、 如果n=3,a={1,2,1},那么第二个喷泉的范围是1到3。所以只需要一个喷泉。这里1号喷泉的射程为1到2, 2号喷泉的射程为1到3,3号喷泉的射程为2到3 因此,只有喷泉2足以被激活覆盖整个花园。 指定最强大的喷泉,使其覆盖1到2*范围-1 从花园中移除指定的喷泉和1到2*范围

从1到n有一个线性花园。每一处都有一个喷泉。给定数组a[n]告诉有关喷泉的信息,其范围是喷泉左侧的max(i-a[i],1)到喷泉右侧的min(i+a[i],n)。找到需要激活的喷泉的最小数量,以覆盖整个花园。 e、 如果n=3,a={1,2,1},那么第二个喷泉的范围是1到3。所以只需要一个喷泉。这里1号喷泉的射程为1到2, 2号喷泉的射程为1到3,3号喷泉的射程为2到3 因此,只有喷泉2足以被激活覆盖整个花园。

  • 指定最强大的喷泉,使其覆盖1到2*范围-1
  • 从花园中移除指定的喷泉和1到2*范围-1
  • 重现

    • 我认为您正在寻找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;
          }
      
      public int findminactivatedfauntain(int[]arr,int n){
      int[]间隔=新的int[n];
      整数计数=1;
      //在每个索引处,我们将存储此索引中可能的最大右键。
      对于(int i=1;i
      • 时间复杂度-O(n)
      • 将范围的下限和上限存储在数组中(下面是fountainArray)
      • 拿一个烟囱,选择你需要的所有喷泉。最初烟囱是空的
      rightLimit=0;
      leftLimit=0;
      对于(i=0;i喷泉光线[i].rightLimit){
      if(leftLimit)leftLimit of
      //烟囱顶部的喷泉
      }
      喷泉塔顶推(喷泉塔顶推[i]);
      }
      }
      返回喷泉安装长度();
      
      遍历所有喷泉并构建阵列跳跃:

      跳跃[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);
      }
      
      for(inti=1;i
      publicstaticintfind(intarr[],intn){
      
      对于(inti=1;iRavi的答案是正确的,但其中有一个小错误

      // 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 i=1;i)您的问题是什么?请参考$
      https://stackoverflow.com/questions/how-to-ask
      $以获得有关代码的帮助。@ravenpoint问题是什么?完成作业?这实际上是一个面试问题。谢谢回答。实际上范围是喷泉左侧的max(i-a[i],1)和min(i+a[i],n)在喷泉的右边。你能给我一个dp解决方案吗?什么是“dp解决方案”?使用动态编程的解决方案你为什么想要这么复杂的事情。简单的递归将在几行代码中给出答案。再多几行代码,你也可以使用for循环(递归让一些人害怕)不包括所有角落的案件为我工作…谢谢:)
      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;
      }
      
      // 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;
          }