正數陣列的最小不可組成和

2021-09-26 08:04:24 字數 1667 閱讀 3035

題目

給定乙個正數陣列arr,其中所有的值都是整數,以下是最小不可組成和的概念:把arr每個子集內的所有元素加起來會出現很多值,其中最小的記為min,最大的記為max。在區間[min, max]上,如果有數不可以被arr某乙個子集相加得到,那麼其中最小的那個數就是arr的最小不可組成和。在區間[min, max]上,如果所有的數都可以被arr的某乙個子集相加得到,那麼max + 1是arr的最小不可組成和。

高階題目

如果已知正數陣列arr中肯定有1這個數,是否能更快地得到最小不可組成和

原問題:使用動態規劃。arr中所有數的相加和sum即是該陣列的最大累加和,所有arr子集的累加和必然在[0, sum]區間上。生成長度為sum+1的dp陣列,dp[i] == true表示i這個累加和可以被arr的子集相加得到,否則不能。如果arr[0…i]這個範圍上的數組成的子集可以累加出k,那麼arr[0…i+1]這個範圍上的數組成的子集中必然可以累加出k + arr[i+1]。時間複雜度o(n*sum),空間複雜度o(sum)

def unformedsum1(arr):

import sys

if arr == none or len(arr) == 0:

return 1

summax = 0

summin = sys.maxsize

for i in range(len(arr)):

summin = min(summin,arr[i])

summax += arr[i]

dp = [false for i in range(summax+1)]

dp[0] = true

for i in range(len(arr)):

for j in range(summax,arr[i]-1,-1):

if dp[j-arr[i]]:

dp[j] = true

for i in range(summin,len(dp)):

if not dp[i]:

return i

return summax + 1

高階問題:具體過程如下:將arr進行排序,排序後必然有arr[0] == 1。從左往右計算每個位置i的range。range表示當計算到位置arr[i]時,[1, range]上所有的數都可以被arr[0…i-1]的某乙個子集累加出來。初始時range = 0。如果arr[i] > range+1。說明在arr[0…i]上,range+1這個數一定不能累加出來。此時返回range + 1即可。如果arr[i]≤range+1arr[i]≤range+1,說明[1,range+arr[i]]區間上所有的正數都可以被arr[0…i]上的某乙個子集累加出來,所以令range += arr[i],然後繼續計算下乙個位置。時間複雜度o(nlogn),空間複雜度o(1)。

def unformedsum2(arr):  

if arr == none or len(arr) == 0:

return 1

arr.sort()

range_ = 0

for i in range(len(arr)):

if arr[i] <= range_ + 1:

range_ += 1

else:

break

return range_+1

正數陣列的最小不可組成和

給定乙個正整數陣列arr,其中所有的值都為整數,以下是最小不接組成和的概念 arr 1,2,3,4 返回11 arr 2,3,4 返回7 public intbaoli intarr for int i min 1 i integer.max value i return0 public void ...

正數陣列的最小不可組成和

正數陣列的最小不可組成和 給定乙個正數陣列arr,其中所有的值都為整數,以下是最小不可組成和的概念 請寫函式返回正數陣列arr的最小不可組成和 時間複雜度為o n i 1nar ri o n times sum n arr i o n i 1n arri 額外空間複雜度為o i 1n arri o ...

正數陣列的最小不可組成和 高階問題

正數陣列的最小不可組成和 高階問題 給定乙個正數陣列arr,其中所有的值都為整數,以下是最小不可組成和的概念 請寫函式返回正數陣列arr的最小不可組成和 保證1一定出現過!要求 時間複雜度為o n logn o nlogn o nlog n 額外空間複雜度為o 1 o 1 o 1 輸入描述 第一行乙...