简体   繁体   English

从序列中选择三个数字,使它们的总和小于一个值

[英]Choose three numbers from a sequence such that their sum is less than a value

Let's say I have an sequence of numbers : 假设我有一个数字序列:

1, 2, 3, 4, 5, 2, 4, 1 1,2,3,4,5,2,4,1

I wonder about algorithm which could say how many possible ways of choosing 3 numbers from sequence above exist, such that their sum doesn't exceed 7? 我对算法可以说从上面的序列中选择3个数字有多少种可能的方式,以使它们的总和不超过7,感到疑惑

I was asked to write a program to solve the problem. 我被要求写一个程序来解决这个问题。 Are there any program techniques I can use? 我可以使用任何编程技术吗?

I will be appreciate your answer! 感谢您的答复!

To get the lowest 3-sum possible, you will simply need to choose the lowest 3 numbers. 要获得最低的3和,您只需选择最低的3个数字。 If this number is lower than the given number - you are done. 如果此数字小于给定的数字-完成。 Otherwise you can answer - there is no such solution, since every other sum you get is bigger than the one you just found, which by its own is bigger than the desired number. 否则,您可以回答-没有这样的解决方案,因为您获得的所有其他总和都比您刚刚发现的总和还要大,而后者本身大于所需的数字。

If you wish to find out "How many different summations there are to a number smaller than the given number", that's a different problem, that can be solved using Dynamic Programming in O(n*number*3) = O(n*number) : 如果您想找出“给定的数字小于某个数字,有多少个不同的和”,那就是一个不同的问题,可以使用O(n*number*3) = O(n*number) 动态编程来解决。 O(n*number*3) = O(n*number)

f(x,i,3) = (x <+ 0 ? 0 : 1)
f(_,n,_) = 0 //out of bound
f(x,i,used) = f(x-arr[i],i+1, used + 1) + f(x,i+1,used)

Invoke with f(number,0,0) f(number,0,0)调用

The following program written in Python 3.4.1 gives one solution that may help you with the problem. 以下用Python 3.4.1编写的程序提供了一种可以帮助您解决该问题的解决方案。

NUMBERS = 1, 2, 3, 4, 5, 2, 4, 1
TARGET = 7
USING = 3

def main():
    candidates = sorted(NUMBERS)[:USING]
    if sum(candidates) <= TARGET:
        print('Your numbers are', candidates)
    else:
        print('Your goal is not possible.')

if __name__ == '__main__':
    main()

Edit: 编辑:

Based on your comment that you want all possible solutions, the following provides this information along with the number of unique solutions. 根据您对所有可能解决方案的意见,以下内容提供了此信息以及许多独特的解决方案。 A solution is considered to be the same as another if both have the same numbers in them (regardless of order). 如果一个解决方案中都有相同的数字(不考虑顺序),则认为该解决方案与另一个解决方案相同。

import itertools

NUMBERS = 1, 2, 3, 4, 5, 2, 4, 1
TARGET = 7
USING = 3

def main():
    # Find all possible solutions.
    solutions = []
    for candidates in itertools.combinations(NUMBERS, USING):
        if sum(candidates) <= TARGET:
            print('Solution:', candidates)
            solutions.append(candidates)
    print('There are', len(solutions), 'solutions to your problem.')
    # Find all unique solutions.
    unique = {tuple(sorted(answer)) for answer in solutions}
    print('However, only', len(unique), 'answers are unique.')
    for answer in sorted(unique):
        print('Unique:', answer)

if __name__ == '__main__':
    main()

Use recursion. 使用递归。 A C++ solution: C ++解决方案:

void count(std::vector<int>& arr, int totalTaken, int index, int currentSum, int expectedSum, int *totalSolutions){
        if (index == arr.size()) return;
        if (totalTaken == 3)
            if (currentSum <= expectedSum)
                (*totalSolutions)++;
            else return;
        count(arr, totalTaken++, idex++, curentSum+arr[index],expectedSum, totalSolutions)
        count(arr, totalTaken, index++, currentSum, expectedSum, totalSolutions)
    }

Call with count(your_vector,0,0,0,expectedSum,ptr2int) after the function has exectuted, you will have your result stored in *ptr2int 函数执行完后,使用count(your_vector,0,0,0,expectedSum,ptr2int)进行调用,结果将存储在*ptr2int

It is possible to obtain O(n^2) time complexity using two pointers technique: 使用两个指针技术可以获得O(n ^ 2)时间复杂度:

  1. Sort the numbers. 对数字进行排序。
  2. Let's fix the middle number. 让我们确定中间的数字。 Let's assume that its index is mid. 假设它的索引为中。
  3. For a fixed mid, you can maintain two indices: low and high. 对于固定的中点,您可以维持两个指数:低和高。 They correspond to the smallest and the biggest number in a sum. 它们在总和中对应于最小和最大的数字。 Initially, low = mid - 1 and high = mid + 1. 最初,低=中-1,高=中+ 1。
  4. Now you can increment high by one in a loop and decrement low as long as the sum of 3 numbers is greater then S. For a fixed high and mid, low shows how many numbers can added to a[mid] and a[high] so that thier sum is <= S. Note that for a fixed mid, high can be incremented O(n) times and low can be decremented only O(n) times. 现在,您可以将一个循环中的高数字递增1,而只要3个数字的总和大于S,就可以将其递减。对于固定的高和中,低显示可以向a [mid]和a [high]添加多少个数字因此,它们的总和<=S。请注意,对于固定的中点,高只能增加O(n)倍,而低只能减少O(n)倍。 Thus, time complexity is O(n^2). 因此,时间复杂度为O(n ^ 2)。

This algorithm requires only O(1) additional space(for low, mid and high indices). 该算法仅需要O(1)个额外空间(用于低,中和高索引)。

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

相关问题 从给定数字求和到给定值的序列? - Finding a sequence from given numbers that sum to given value? sum 小于或等于 N 的数的除数之和 - sum's sum of divizors of numbers less than or equal to N 使用线段树在一个范围内小于 k 的所有数字的总和 - Sum of all numbers less than k in a range using segment tree 从总和小于m且大于r的n个数组中返回所有可能的排列和数字组合 - Return all possible permutations and combinations of numbers from n arrays whose sum is less than m and greater than r 使用小于或等于 k ​​的数字对数字求和的不同方法 - Different ways to sum a number using numbers less than or equal to k 找到总和小于S的所有数字对 - Find all pairs of numbers whose sum is less than S 给出数字排列以使相邻差之和小于2的算法 - Algorithm that gives a permutation of numbers such that the sum of the adjacent differences is less than 2 从数组中删除元素,使总和小于或等于特定值。 (不是子阵列) - Removing elements from an array such that the sum becomes less than or equal to a particular value. (Not subarray) 制作序列的数字之和 - Sum of numbers making a sequence 总和最大但小于特定值的子集 - SubSet whose sum is greatest but less than a particular value
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM