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
Algorithm 给定一个整数数组,使用数组的数字求最大数,使其可被3整除_Algorithm_Dynamic Programming_Greedy - Fatal编程技术网

Algorithm 给定一个整数数组,使用数组的数字求最大数,使其可被3整除

Algorithm 给定一个整数数组,使用数组的数字求最大数,使其可被3整除,algorithm,dynamic-programming,greedy,Algorithm,Dynamic Programming,Greedy,例如:数组:4,3,0,1,5{假设所有数字都>=0。数组中的每个元素都对应一个数字。即数组中的每个元素都在0和9之间。} 在上面的数组中,最大的数字是:5430{使用数组中的数字5、4、3和0} 我的做法: 对于被3整除的情况,我们需要数字之和被3整除。 所以 步骤1:从数组中删除所有零 步骤2:这些零将在末尾出现。{因为它们不影响和,我们必须找到最大的数} 第三步:找到数组元素的子集(不包括零),使位数最大,位数之和最大,且总和可被3整除 步骤4:所需数字由上述集合中按降序排列的数字组成 因

例如:数组:4,3,0,1,5{假设所有数字都>=0。数组中的每个元素都对应一个数字。即数组中的每个元素都在0和9之间。}

在上面的数组中,最大的数字是:5430{使用数组中的数字5、4、3和0}

我的做法:

对于被3整除的情况,我们需要数字之和被3整除。 所以

  • 步骤1:从数组中删除所有零
  • 步骤2:这些零将在末尾出现。{因为它们不影响和,我们必须找到最大的数}
  • 第三步:找到数组元素的子集(不包括零),使位数最大,位数之和最大,且总和可被3整除
  • 步骤4:所需数字由上述集合中按降序排列的数字组成
  • 因此,主要步骤是步骤3,即如何找到子集,使其包含尽可能多的元素,使其总和最大,并可被3整除

    我在想,也许第三步可以通过贪婪的选择来完成,即获取所有元素,然后继续移除集合中最小的元素,直到总和可以被3整除

    但我不相信这种贪婪的选择会奏效

    请告诉我我的方法是否正确。 如果是,那么请建议如何执行步骤3


    此外,请建议任何其他可能/有效的算法。

    观察:如果您可以得到一个可被3整除的数字,您最多需要删除2个数字,以保持最佳解决方案

    一个简单的
    O(n^2)
    解决方案是检查删除1个数字的所有可能性,如果没有有效的,检查所有对(其中有
    O(n^2)


    编辑:
    O(n)
    解决方案:创建3个桶-
    bucket1
    bucket2
    bucket0
    。每个将表示数字的模数3值。在下一个算法中忽略bucket0

    让数组的和为
    sum

    If sum % 3 ==0: we are done.
    else if sum % 3 == 1:
      if there is a number in bucket1 - chose the minimal
      else: take 2 minimals from bucket 2
    else if sum % 3 == 2
      if there is a number in bucket2 - chose the minimal
      else: take 2 minimals from bucket1  
    
    注意:要获得
    O(1)
    空间,您实际上不需要bucket-您只需要
    bucket1
    bucket2
    中的2个最小值,因为它是我们从这些bucket中实际使用的唯一数字

    示例:

    arr = { 3, 4, 0, 1, 5 }
    bucket0 = {3,0} ; bucket1 = {4,1} bucket2 = { 5 }
    sum = 13 ; sum %3 = 1
    bucket1 is not empty - chose minimal from it (1), and remove it from the array.
    result array = { 3, 4, 0, 5 } 
    proceed to STEP 4 "as planned"
    

    贪婪选择绝对不起作用:考虑SET <代码> { 5, 2, 1 } < /代码>。您应该先删除

    1
    ,但应该删除
    2

    我想你应该算出数组模3的和,它要么是0(你完成了),要么是1,要么是2。然后你要删除模3和为1或2的最小子集

    我认为这相当简单,因此不需要动态编程。如果可能的话,用该模去掉一个数字,否则用另一个模去掉两个数字。一旦知道要删除多少,请选择尽可能小的。你永远不需要删除三个数字

    您不需要特别处理
    0
    ,但如果要这样做,则可以在步骤3中进一步减少正在考虑的集合,前提是临时删除其中的所有0、3、6、9

    总而言之,我可能会:

    • 按降序排列数字
    • 计算模量。如果为0,则完成
    • 从末尾开始,尝试删除具有该模数的数字。如果成功,我们就完蛋了
    • 从末尾开始,删除两个模数为负的数字。这总是成功的,所以我们结束了
    • 我们可能会留下一个空数组(例如,如果输入是
      1,1
      ),在这种情况下,问题是不可能的。否则,数组将包含结果的数字

    如果在步骤1中进行计数排序,则时间复杂度为
    O(n)
    。当然可以,因为值是数字。

    您对此有何看法:

    首先按值对数组元素进行排序

    sum up all numbers
    - if sum's remainder after division by 3 is equal to 0, just return the sorted
      array
    - otherwise
        - if sum of remainders after division by 3 of all the numbers is smaller
          than the remainder of their sum, there is no solution
        - otherwise
            - if it's equal to 1, try to return the smallest number with remainder
              equal to 1, or if no such, try two smallest with remainder equal to 2,
              if no such two (I suppose it can happen), there's no solution
            - if it's equal to 2, try to return the smallest number with remainder
              equal to 2, or if no such, try two smallest with remainder equal to 1,
              if no such two, there's no solution
    
    首先将数组元素按除3的余数升序排序
    然后等余数的每个子集按值降序排序

    首先,该问题归结为最大化所选元素的数量,使其总和可被3整除

    平凡:选择所有可被3(0,3,6,9)整除的数字

    Le a是留下1作为余数的元素,b是留下2作为余数的元素。如果(| a |-| b |)%3为0,则从a和b中选择所有元素。如果(| a |-| b |)%3为1,则从b中选择所有元素,并从a中选择| a |-1个最高数字。如果余数为2,则从a中选择所有数字,从b中选择| b |-1个最高数字

    一旦你有了所有的数字,把它们按相反的顺序排序并连接起来。这就是你的答案

    最终,如果n是元素数,则该算法返回一个长度至少为n-1位的数字(角点情况除外,见下文)

    注意:注意角落的情况(即| a |=0或| b |=0等)。(-1)%3=2和(-2)%3=1


    如果m是字母表的大小,n是元素的数量,那么我的算法是O(m+n)

    因为只有十个不同的值,所以不需要对数据进行排序。 如果给定n个数字,只需计算O(n)中的0、1、2等数。 计算所有数字之和,检查余数模3是0、1还是2

    如果剩余值为1:删除以下可能的第一项(其中一项保证是可能的):1、4、7、2+2、2+5、5+5、2+8、5+8、8+8

    如果剩余部分为2:删除以下可能的第一项(其中一项保证是可能的):2、5、8、1+1、1+4、4+4、1+7、4+7、7+7

    如果没有剩余数字,则问题无法解决。否则,解决方案是通过将剩余的9、8、7等连接起来创建的

    (分类