簡體   English   中英

從數字列表中找到所有不同總和的算法

[英]An algorithm to find all distinct sums from a list of numbers

輸入樣例:

4 6 4 3 2 2 1 1

第一個數字=總數T(T <1000)

第二個數字=數字數量S(S <= 12)

跟隨S個數字=數字的值(每個值<100)。 (可能發生重復,輸入以非遞增順序給出)

我的工作是使用列表中加起來為T的數字找到所有“不同的和”。

因此,該輸入的樣本輸出為:

4
3+1
2+2
2+1+1

我的想法是逐一遍歷列表,找到一個具有不同數字的數字的所有組合,直到數字列表的大小-已評估的數字數量。 您可以從每個組合中創建一個列表,然后將該列表添加到列表的HashSet中(HashSet可以防止重復)。

因此,您需要先檢查所有1、2、3、4、5和6尺寸的組合是否與4匹配,然后檢查所有1、2、3、4、5尺寸的組合與3的匹配,而忽略4所有1,2,3,4尺寸的組合與2,一起使用,忽略4和3

等等

  1. 我不確定這個算法是否真的有效
  2. 我都很難實現該算法。 我無法圍繞如何循環結構來獲得所需的組合。

您應該嘗試遞歸解決方案。 通常,您只需要處理以下想法:對於每個數字,您都可以將其包括在總和中,也可以不包括。 這意味着您正在構建數字的冪集,並且將得到O(2^N)解決方案。

簡短地用偽代碼:

def get_all_sums(arr, target):

    result = []

    def helper(index, current_arr, current_sum):

        # once you've gone over the arr you can return. If all your numbers are positive
        # you can also return early if the current_sum > target
        if index == len(arr): return

        # solution found - add it to the result
        if current_sum == target: result.append(current_arr)

        # include the current index
        helper(index + 1, current_arr + [arr[index]], current_sum + arr[index])

        # don't include the current index
        helper(index + 1, current_arr, current_sum)

    helper(0, [], 0)

    # sort and hash to get rid of duplicates; return a set
    return {tuple(sorted(i) for i in result)}

可以通過簡單的遞歸找到答案,我將使用問題中的示例進行演示。

在遞歸的第一級,要解決的問題是

target=4 count=6 allowed={4,3,2,2,1,1} chosen={}

第一級選擇循環中的每個唯一值,然后進行遞歸調用。 因此,第一層的遞歸調用是

target=0 size=5 allowed={3,2,2,1,1} chosen={4}
target=1 size=4 allowed={2,2,1,1} chosen={3}
target=2 size=3 allowed={2,1,1} chosen={2}
target=3 size=1 allowed={1} chosen={1}

關鍵是允許值的數組在每個遞歸級別上都變小。 只能使用跟隨所選值的那些值。 因此,例如,當第一級遞歸選擇值3時,則僅允許小於3的值。 如果是重復項,則選擇第一個重復項,並且將允許的值限制為其余重復項和任何較小的值。


在第二級遞歸時,參數為

target=0 size=5 allowed={3,2,2,1,1} chosen={4}

這是成功的基本情況: target為0。在這種情況下, 將{4}添加到輸出列表中 ,因為這是一個解決方案。


在第二級遞歸時,參數為

target=1 size=4 allowed={2,2,1,1} chosen={3}

代碼應跳過2,因為2比目標大。 所以唯一的遞歸調用是

target=0 size=1 allowed={1} chosen={3,1}

這也是基本情況,因此第三級遞歸會將{3,1}添加到輸出中


在第二級遞歸時,參數為

target=2 size=3 allowed={2,1,1} chosen={2}

將有兩個遞歸調用

target=0 size=2 allowed={1,1} chosen={2,2}
target=1 size=1 allowed={1} chosen={2,1}

第一個是基本情況,因此將{2,2}添加到輸出中 另一個遞歸調用最終會將{2,1,1}添加到輸出中


在第二級遞歸時,參數為

target=3 size=1 allowed={1} chosen={1}

有一個遞歸調用

target=2 size=0 allowed={} chosen={1,1}

這是失敗的基本情況: target非零且size為0。


請注意,以這種方式解決問題后,僅生成唯一的解決方案,因此無需刪除重復的解決方案。

還要注意,最大遞歸深度由S決定,因此將S限制在一個合理的小數值( S <= 12表示相當小)很重要。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM