简体   繁体   English

给定N,找到添加的最大*奇数/偶数*数来得到N.

[英]Given N, find the maximum *odd/even* numbers added to get N

I'd like to ask a follow-up question base on this one: Given n, find the maximum numbers added to get n 我想根据这个问题提出一个后续问题: 给定n,找到为获得n而添加的最大数字

What if I can only use odd numbers to sum up N. Is there any formula to generalise it? 如果我只能使用奇数来总结N.如果有任何公式可以推广它怎么办? Thanks! 谢谢!

eg Given 7, ans is 1, for 7 Given 16, ans is 4, for 1+3+5+7 Given 13, ans is 3, for 1+5+7 例如,给定7,ans为1,对于7给定16,ans为4,对于1 + 3 + 5 + 7给定13,ans为3,对于1 + 5 + 7

I'm going to propose code that solves your question, then attempt to prove/defend it. 我将提出解决你的问题的代码,然后尝试证明/捍卫它。

  public static int maxOddSumToInt(final int n) throws IllegalArgumentException {
    if(n < 0) throw new IllegalArgumentException("n must be positive");

    LinkedList<Integer> currentNums = new LinkedList<>();
    currentNums.add(1);
    int sum = 1;
    int next = 3;
    while(sum < n) {
      currentNums.add(0, next);
      sum += next;
      next += 2;
    }
    while (sum > n) {
      int r = currentNums.remove(0);
      sum -= r;
      while(sum < n) {
        currentNums.set(0, currentNums.get(0) + 2);
        sum += 2;
      }
    }
    return currentNums.size();
  }

The key of your problem is that you just want the count of the most unique odd integers summing to the target. 问题的关键在于您只需要计算与目标相加的最独特的奇数整数。 Thus it doesn't matter how we arrive at that maximum count, just that we are sure that we have it. 因此,我们如何达到最大数量并不重要,只要我们确信我们拥有它。

The fast track to using the most numbers is to use the smallest ones possible. 使用最多数字的快速通道是使用尽可能小的数字。 Thus we would want to use 1,3,5,7,9, ... instead of 1,9,15, for example. 因此,我们想要使用1,3,5,7,9,...而不是1,9,15。 Thus, the first step is including as many numbers in ascending order as we can, until we hit or exceed our target. 因此,第一步是尽可能多地按升序包括数字,直到达到或超过我们的目标。 If we hit it, great! 如果我们点击它,太棒了! That is by definition the maximally sized set of numbers to use, because there are no smaller numbers left available. 根据定义,这是要使用的最大数量的数字集,因为没有可用的较小数字。 For example, for the input "9", the algorithm will add 1, add 3, add 5, see that it hit 9 and return the size 3. 例如,对于输入“9”,算法将添加1,添加3,添加5,看到它命中9并返回大小3。

If we exceed the target, we remove the last addition, as this clearly made it no longer possible. 如果我们超过目标,我们删除最后一个添加,因为这显然使它不再可能。 By similar logic to above, this means that any set of the size we were at ( n ) won't work, as we had the minimum summing set before and even that was too large. 通过与上面类似的逻辑,这意味着我们在( n )处的任何大小的集合将不起作用,因为我们之前设置了最小的求和,甚至太大了。 Thus we try sets of size n-1 . 因此,我们尝试大小为n-1集合。 From here, it doesn't matter how we try to get to our target, just that we check to see if any set of size n-1 works. 从这里开始,我们如何尝试达到目标并不重要,只是我们检查是否有任何大小的n-1工作。 Thus for simplicity we increase the most recent addition by 2 repeatedly to see if we hit the target. 因此,为简单起见,我们反复增加最近的加法2 ,以查看我们是否达到了目标。 This both ensures that we aren't repeating a number (we are making the largest one larger, thus it isn't possible for it to become a duplicate) and that if we exceed to the target again and need to repeat this step, we can do one removal and certainly drop below our target again. 这两者都确保我们不重复一个数字(我们正在制作一个更大的数字,因此它不可能成为重复)并且如果我们再次超过目标并需要重复这一步骤,我们可以做一次删除,并肯定再次低于我们的目标。

Total time complexity is a bit tricky. 总时间复杂度有点棘手。 I think I can claim that it's O(N^2) at the very worst, where N is the value of the target. 我想我可以声称它是最坏的O(N^2) ,其中N是目标的值。 The worst case scenario is that the number can only be represented by itself (a set of size 1), so we build a set summing till we exceed it ( O(N) ), and remove each while incrementing till we exceed again ( N*O(N) ). 最糟糕的情况是这个数字只能用它自己来表示(一组大小为1),所以我们建立一个集合求和直到我们超过它( O(N) ),然后逐渐移除,直到我们再次超过( N*O(N) )。 There may be a tighter bound based on number stuff, but not off the top of my head. 基于数字的东西可能会有更严格的限制,但不是我的头脑。

The one thing the algorithm doesn't do is gracefully handle invalid inputs. 算法不做的一件事就是优雅地处理无效输入。 If you give it a number that doesn't have a solution it will run forever. 如果你给它一个没有解决方案的数字,它将永远运行。 If you can figure out a simple numeric test for this you can just add it to the illegal argument exception at the top. 如果你可以为此找出一个简单的数值测试,你可以将它添加到顶部的非法参数异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM