Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过删除数字计算最大点数的算法_Java_Algorithm - Fatal编程技术网

Java 通过删除数字计算最大点数的算法

Java 通过删除数字计算最大点数的算法,java,algorithm,Java,Algorithm,我正在经历这个过程,从两天以来,我通过多次阅读解释试图理解它,但我无法理解程序是如何解决的 以下是问题陈述: 给定整数数组nums,可以对 数组 在每个操作中,您选择任何NUM[i]并将其删除以赚取NUM[i] 要点。之后,必须删除等于nums[i]-1或 nums[i]+1 你从0分开始。返回您可以获得的最大点数 通过应用这些操作来赚取利润 示例1:输入:nums=[3,4,2]输出:6说明:删除4到 获得4分,因此3分也被删除。然后,删除2以赚取 2分。总共获得6分 以下是关于如何解决该问题

我正在经历这个过程,从两天以来,我通过多次阅读解释试图理解它,但我无法理解程序是如何解决的

以下是问题陈述:

给定整数数组nums,可以对 数组

在每个操作中,您选择任何NUM[i]并将其删除以赚取NUM[i] 要点。之后,必须删除等于nums[i]-1或 nums[i]+1

你从0分开始。返回您可以获得的最大点数 通过应用这些操作来赚取利润

示例1:输入:nums=[3,4,2]输出:6说明:删除4到 获得4分,因此3分也被删除。然后,删除2以赚取 2分。总共获得6分

以下是关于如何解决该问题的解释:

算法

对于NUM的每个唯一值k,按递增顺序,让我们保持 avoid和using的正确值,表示以下情况的答案: 我们不分别取k或k

如果新值k与先前最大值prev相邻, 如果我们必须取k,答案是(k的点值)+避免, 如果我们不能取k,答案是max(避免,使用)。 类似地,如果k与prev不相邻,那么我们必须取k 是(k的点值)+max(避免,使用),如果我们 不得采用k为最大值(避免,使用)

最后,最佳答案可能会也可能不会使用中的最大值 nums,因此我们返回max(避免,使用)

以及相应的Java程序:

public int deleteAndEarn(int[] nums) {
        int[] count = new int[10001];
        for (int x: nums) count[x]++;
        int avoid = 0, using = 0, prev = -1;

        for (int k = 0; k <= 10000; ++k) if (count[k] > 0) {
            int m = Math.max(avoid, using);
            if (k - 1 != prev) {
                using = k * count[k] + m;
                avoid = m;
            } else {
                using = k * count[k] + avoid;
                avoid = m;
            }
            prev = k;
        }
        return Math.max(avoid, using);
    }
public int deleteandarn(int[]nums){
int[]计数=新的int[10001];
对于(整数x:nums)计数[x]++;
int avoid=0,using=0,prev=-1;
对于(int k=0;k 0){
int m=Math.max(避免,使用);
如果(k-1!=上一个){
使用=k*计数[k]+m;
避免=m;
}否则{
使用=k*计数[k]+避免;
避免=m;
}
prev=k;
}
返回Math.max(避免,使用);
}
我无法理解这里如何使用
avoid
using
变量,以及如何解决问题陈述


你能帮我理解这一点吗。

我在那一页上解决了这个问题。 该算法基于一个非常好的技巧。如果在应用算法之前先处理输入,则很容易解决此问题。 输入被重新组织为bucket

假设您有输入:
123244

你可以把它重新组织成

(Two 1s), (Three 2s), ( Two 3s), (Three 4s)
现在根据问题,如果你选择了任何一个bucket,你应该放弃包含(bucket元素值-1)和(bucket元素值+1)的bucket,它们实际上与这个bucket相邻

现在的问题归结为,在无法获得相邻存储桶值的约束条件下,如何选择存储桶以获得最大和

这很简单——当你通过水桶时,你可以用水桶做两件事。要么避免它,要么使用它

如果你避免它,你能达到的最大量是多少?这取决于你对前一个做了什么

amountWhenAvoided[i] = Math.max( amountWhenAvoided[i-1], amountWhenTaken[i-1] );
如果你使用它,你能达到的最大数量是多少?你得到了这个桶的价值+你离开/避开前一个桶时得到的任何东西

amountWhenTaken[i] = amountWhenAvoided[i-1] + valueOfBucket[i]
一旦到达桶的末端,答案将是:

Math.max( amountWhenTaken[n], amountWhenAvoided[n] )
您可以编写如下代码:

public int deleteAndEarn( int[] nums ) {
  //reorganize.
  int[] valueOfBucket= new int[10001] //This is the maximum size of the buckets.

  for ( int num : nums ) {
     valueOfBucket[num] += num; //Populate each bucket.
  }

  //Now go through each bucket - remember - a bucket could be empty that's fine.
  int[] amountWhenTaken = new int[n];
  int[] amountWhenAvoided = new int[n];
  amountWhenTaken[0] = 0; //Because there are no buckets to start with - buckets start from 1
  amountWhenAvoided[0] = 0;
  for ( int i = 1; i <= n; i++ ) {
     amountWhenAvoided[i] = Math.max( amountWhenAvoided[i-1], amountWhenTaken[i-1] );
     amountWhenTaken[i] = amountWhenAvoided[i-1] + valueOfBucket[i];
  }
  return Math.max( amountWhenTaken[n], amountWhenAvoided[n] );
}

您是否使用调试器一步一步地检查代码以观察“目标函数”是如何工作的?您是否不理解如何解决它或代码如何与之对应的解释?@Micromoncher,是的,尝试使用eclipse进行调试IDE@juvian,我通过解释理解了代码。但是我无法理解这个解释。
public int deleteAndEarn( int[] nums ) {
      //reorganize.
      int[] valueOfBucket= new int[10001] //This is the maximum size of the buckets.

      for ( int num : nums ) {
         valueOfBucket[num] += num; //Populate each bucket.
      }

      //Now go through each bucket - remember - a bucket could be empty that's fine.
      int using_prev = 0;
      int avoiding_prev = 0;
      int avoiding_curr = 0;
      int using_curr = 0;
      for ( int i = 1; i <= n; i++ ) {
         avoiding_curr = Math.max( avoiding_prev, using_prev);
         using_curr = avoiding_prev + valueOfBucket[i];
         avoiding_prev = avoiding_curr;
         using_prev = using_curr;
      }
      return Math.max( avoiding_curr, using_curr );
 }