当前位置: 首页 > 知识库问答 >
问题:

求给定和的极小子集

黄元章
2023-03-14

我在Scala中做了一个问题,这是任务语句的摘要:

上述示例的输出:
1
2
3
-1

第一行是数组长度,第二行是整数数组(0

以下是我尝试的:选择的元素并不重要。所以我先对给定整数的列表排序最大。然后我选择了第一个元素,检查它是否大于S,如果不大于S,我也选择了第二个元素,依此类推,直到总和大于或等于S。

我的代码(Scala):

object Solution {
  def main(args: Array[String]) {
    val n = readInt()
    val arr: Array[Long] = readLine().split(" ").map(_.toLong).sortWith(_ > _)

    val sums: Array[BigInt] = new Array(n)
    sums(0) = arr(0)
    for(i <- 1 until n) sums(i) = sums(i-1) + arr(i)

    val t = readInt()
    for(i <- 1 to t) {
      val s:BigInt = BigInt(readLong())
      if(sums(n-1) < s)
        println(-1)

      else {
        var i = 0
        while(sums(i) < s) i += 1
        println(i + 1)
      }
    }
  }
}

共有1个答案

穆季萌
2023-03-14

创建一个完整的和列表是不必要的,而且使用bigint无论如何都是浪费的--一个long最多可以容纳9.2e18,并且您被保证只会出现1e15。(事实上,我认为选择1E15是为了即使是double也能保持答案而不损失精度。)

此外,您可以对基元使用快速排序,而不是使用诸如_>_这样的慢速泛型排序,后者最终装箱整数。所以:

val arr = {
  val in = readLine().split(' ').map(_.toInt)
  java.util.Arrays.sort(in)
  in
}

然后,使用累加器(long即可):

var sum = 0L

并使用while循环搜索答案,记住最大的元素是最后一个,所以您希望从结尾开始:

var i = arr.length-1
while (i >= 0 && sum < t) {
  sum += arr(i)
  i -= 1
}

现在您只需要在用完元素之前检查成功还是失败:

val answer = {
  if (i < 0) -1
  else arr.length - i - 1
}
 类似资料:
  • 问题陈述如下: 当帖子说解决方案对负数不起作用时,它指的是哪些输入情况?

  • 给出不同整数的列表 我的想法:< br >一种简单的方法是一个接一个地选择一个元素,看看它形成的完美子集的大小,然后我们可以简单地返回最大值。这将是计算密集型的。< br >有什么好的解决方案吗

  • 这个问题有多项式解吗?如果有,你能呈现吗?

  • 我正在寻找以下问题的答案。 给定一组整数(无重复项)和一个和,找出集合元素的所有可能组合,并求和。解的顺序并不重要(解{2,2,3}和{3,2,2}是相等的)。 请注意,最终组合不需要是集合,因为它可以包含重复。 示例:集合{2,3,5}和10 结果:{2, 2, 2, 2, 2},{2,2,3,3},{2,3,5},{5,5} 我已经研究过子集和问题以及硬币兑换问题,但不能使它们适应我的需要。我

  • 我有一个数组[1,2,3],总和为4。所以所有的连续子数组都是 [1],[1,2][2,3] 和 [1,2,3]。因此,小于或等于总和的最大长度子数组为 [1,2],长度为 2。 我用下面的方法找到了所有的子数组,并检查了子数组的和,如下所示。但是这种方法不适用于负数。{1,2,1,1,3,-2,-3,7,9};答:7

  • 给定一个数组形式的未排序(多)整数集,求其和大于或等于常量整数x的最小基数子集。 我们的集合是{4 5 8 10 10},x=15,所以最小基数子集和 这个问题与以下问题相关但不同:给定一个n个整数的列表,找到大于X的最小子集和在前面的问题中,作者要求得到一个和最接近X的子集,这里我们想要任何子集