題目
給定乙個正數陣列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 輸入描述 第一行乙...