2021-08-10:给定一个正数数组arr,返回arr的子集不能累加出的最小正数。1)正常怎么做? 2)如果arr中肯定有1这个值,怎么做?

Posted 福大大架构师每日一题

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-08-10:给定一个正数数组arr,返回arr的子集不能累加出的最小正数。1)正常怎么做? 2)如果arr中肯定有1这个值,怎么做?相关的知识,希望对你有一定的参考价值。

2021-08-10:给定一个正数数组arr,返回arr的子集不能累加出的最小正数。1)正常怎么做? 2)如果arr中肯定有1这个值,怎么做?

福大大 答案2021-08-10:

先排序,然后扩充range范围。
1.b<=range+1,扩充到range+b。
2.b>range+1,直接返回range+1。
时间复杂度:排序的。
空间复杂度:排序的。

代码用golang编写。代码如下:

package main

import (
    "fmt"
    "math"
    "sort"
)

func main() {
    arr := []int{1, 2, 5}
    if true {
        ret := unformedSum1(arr)
        fmt.Println(ret)
    }
    if true {
        ret := unformedSum2(arr)
        fmt.Println(ret)
    }
    if true {
        ret := unformedSum3(arr)
        fmt.Println(ret)
    }
}
func unformedSum1(arr []int) int {
    if len(arr) == 0 {
        return 1
    }

    set := make(map[int]struct{})
    process(arr, 0, 0, set)
    min := math.MaxInt64
    for i := 0; i != len(arr); i++ {
        min = getMin(min, arr[i])
    }
    for i := min + 1; i != math.MinInt64; i++ {
        if _, ok := set[i]; !ok {
            return i
        }
    }
    return 0
}

func getMin(a int, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}

func process(arr []int, i int, sum int, set map[int]struct{}) {
    if i == len(arr) {
        set[sum] = struct{}{}
        return
    }
    process(arr, i+1, sum, set)
    process(arr, i+1, sum+arr[i], set)
}

func unformedSum2(arr []int) int {
    if len(arr) == 0 {
        return 1
    }
    sum := 0
    min := math.MaxInt64
    for i := 0; i != len(arr); i++ {
        sum += arr[i]
        min = getMin(min, arr[i])
    }
    // boolean[][] dp ...
    N := len(arr)
    dp := make([][]bool, N)
    for i := 0; i < N; i++ {
        dp[i] = make([]bool, sum+1)
    }
    for i := 0; i < N; i++ { // arr[0..i] 0
        dp[i][0] = true
    }
    dp[0][arr[0]] = true
    for i := 1; i < N; i++ {
        for j := 1; j <= sum; j++ {
            if j-arr[i] >= 0 {
                dp[i][j] = dp[i-1][j] || (dp[i-1][j-arr[i]])
            } else {
                dp[i][j] = dp[i-1][j] || (false)
            }
        }
    }
    for j := min; j <= sum; j++ {
        if !dp[N-1][j] {
            return j
        }
    }
    return sum + 1
}

// 已知arr中肯定有1这个数
func unformedSum3(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    sort.Slice(arr, func(i, j int) bool {
        return arr[i] < arr[j] // O (N * logN)
    })
    range2 := 1
    // arr[0] == 1
    for i := 1; i != len(arr); i++ {
        if arr[i] > range2+1 {
            return range2 + 1
        } else {
            range2 += arr[i]
        }
    }
    return range2 + 1
}

执行结果如下:


左神java代码

以上是关于2021-08-10:给定一个正数数组arr,返回arr的子集不能累加出的最小正数。1)正常怎么做? 2)如果arr中肯定有1这个值,怎么做?的主要内容,如果未能解决你的问题,请参考以下文章

2022-06-16:给定一个数组arr,含有n个数字,都是非负数, 给定一个正数k, 返回所有子序列中,累加和最小的前k个子序列累加和。 假设K不大,怎么算最快? 来自亚马逊。

2021-05-01:给定一个有序数组arr,代表坐落在X轴上的点。给定一个正数K,代表绳子的长度。返回绳子最多压中几个点?即使绳子边缘处盖住点也算盖住。

2022-06-17:给定一个数组arr,含有n个数字,可能有正有负有0, 给定一个正数k。 返回所有子序列中,累加和最大的前k个子序列累加和。 假设K不大,怎么算最快? 来自Amazon。

2022-05-02:给定一个数组arr,一个正数num,一个正数k, 可以把arr中的某些数字拿出来组成一组,要求该组中的最大值减去最小值<=num, 且该组数字的个数一定要正好等于k, 每个数字只

2021-08-28:给定一个正数数组arr,长度一定大于6(>=7),一定要选3个数字做分割点,从而分出4个部分,并且每部分都有数,分割点的数字直接删除,不属于任何4个部分中的任何一个。 返回有没有

2021-06-27:给定一个正数数组arr,代表若干人的体重。再给定一个正数limit,表示所有船共同拥有的载重量。每艘船最多坐两人,且不能超过载重,想让所有的人同时过河,并且用最好的分配方法让船尽