是否和包含

有一個數組 : 3, 34, 4, 12, 5, 2

題目 : 是否有排列組合的和剛好等於 9 例如 : 4, 5 = 9 -> true 但 -1 沒有一個組合可以為他 -> false

思路 :

如上面 於 sub(arr[0~5], 9) 時 選擇是否要從 arr[5] 去做 sum 選擇 arr[5] 做, 下一個 -> sub(arr[0~4], 9 - arr[5]) 不選擇 arr[5] 做, 下一個 -> sub(arr[0~4], 9) 最後 or(選擇 arr[5], 不選 arr[5])

虛擬碼 :

//// 條件 :
// 發生如果 arr[n] 本身的值 > sum
if sum > 0 && arr[n] > sum :
    sub(arr[0~n], sum) = sub(arr[0 ~(n-1)], sum)
// 正常情況 
if sum > 0:
    sub(arr[0~n], sum) = or(sub(arr[0 ~ (n-1)], sum - arr[n]), sub(arr[0 ~ (n-1)], sum))

//// 終止 :
// 正常情況
if sum == 0:
    return true
// 剛好計算到只剩一筆 sub(arr[0], sum)
if len(arr) == 1:
    return arr[0] == sum

code (golang) common

import (
    "fmt"
)

var gWorkArray []int

func prepare(){
    gWorkArray= make([]int, 6)
    gWorkArray[0] = 3
    gWorkArray[1] = 34
    gWorkArray[2] = 4
    gWorkArray[3] = 12
    gWorkArray[4] = 5
    gWorkArray[5] = 2
}

code (golang) 遞迴 (result : true, true, true, false)

func recursive(array []int, sum int) bool{
    arrLen := len(array)
    lastIndex := arrLen - 1
    if sum == 0{
        return true
    }else if arrLen == 1{
        return array[0] == sum
    }else if array[lastIndex] > sum{
        return recursive(array[0: arrLen - 1], sum)
    }else{
        selection := recursive(array[0: arrLen - 1], sum - array[lastIndex])
        noSelection := recursive(array[0: arrLen - 1], sum)
        return selection || noSelection
    }
}

func main(){
    prepare()
    fmt.Println("recursive sum 10 result --> ", recursive(gWorkArray, 10))
    fmt.Println("recursive sum 11 result --> ", recursive(gWorkArray, 11))
    fmt.Println("recursive sum 12 result --> ", recursive(gWorkArray, 12))
    fmt.Println("recursive sum 13 result --> ", recursive(gWorkArray, 13))
}

動態規劃需使用 2 維陣列, 如下圖 (sum = 8)

條件 :

sum = 0 時都為 true, 如下圖

條件 :

len(arr) == 1 時, if sum == arr[n] return true else return false, 如下圖

剩餘的從二維 (1,1) -> (1,2) -> (1,3) 開始去判斷為 true or false 條件 :

if sum > 0 && arr[n] > sum :
    sub(arr[0~n], sum) = sub(arr[0 ~(n-1)], sum)
// 正常情況 
if sum > 0:
    sub(arr[0~n], sum) = or(sub(arr[0 ~ (n-1)], sum - arr[n]), sub(arr[0 ~ (n-1)], sum))

code (golang) 動態規劃 (result : true, true, true, false)

func createDpArray(sum int) [][]bool{
    // optArray[gWorkArray][sum]
    optArray := make([][]bool,len(gWorkArray))
    for i:= 0; i < len(gWorkArray); i++{
        optArray[i] = make([]bool, sum + 1)
    }
    return optArray
}

func dp(sum int) bool{
    dpArray := createDpArray(sum)
    // sum == 0, true
    for i:= 0; i < len(gWorkArray); i++{
        dpArray[i][0] = true
    }

    // gWorkArray's index == 0, sum = gWorkArray[0] = true, other false
    for i:= 0; i < (sum + 1); i++{
        dpArray[0][i] = false
    }
    dpArray[0][gWorkArray[0]] = gWorkArray[0] == sum

    // === other
    for arrayIndex := 1; arrayIndex < len(gWorkArray); arrayIndex++{
        for sumIndex :=1; sumIndex < (sum + 1); sumIndex++{
            if gWorkArray[arrayIndex] > sumIndex{
                dpArray[arrayIndex][sumIndex] = dpArray[arrayIndex - 1][sumIndex]
            }else{
                selection := dpArray[arrayIndex - 1][sumIndex - gWorkArray[arrayIndex]]
                noSelection := dpArray[arrayIndex - 1][sumIndex]
                dpArray[arrayIndex][sumIndex] = selection || noSelection
            }
        }
    }

    return dpArray[len(gWorkArray) - 1][sum]
}

func main(){
    prepare()
    fmt.Println("dp sum 10 result --> ", dp(10))
    fmt.Println("dp sum 11 result --> ", dp(11))
    fmt.Println("dp sum 12 result --> ", dp(12))
    fmt.Println("dp sum 13 result --> ", dp(13))
}

results matching ""

    No results matching ""