(力扣每日一題)分割陣列的最大值

2021-10-08 12:24:47 字數 2679 閱讀 8597

給定乙個非負整數陣列和乙個整數 m,你需要將這個陣列分成 m 個非空的連續子陣列。設計乙個演算法使得這 m 個子陣列各自和的最大值最小。

注意:陣列長度 n 滿足以下條件:

解題思路

方法一動態規劃

1、令 f[i][j]表示將陣列的前 i個數分割為 j 段所能得到的最大連續子陣列和的最小值。

2、進行狀態轉移時,我們可以考慮第 j段的具體範圍,即我們可以列舉 k,其中前 k個數被分割為 j-1 段,而第 k+1到第 i 個數為第 j段。

3、這 j段子陣列中和的最大值,就等於 f[k][j-1]與sub(k+1,i) 中的較大值,其中sub(i,j) 表示陣列 nums 中下標落在區間 [i,j] 內的數的和。

4、狀態轉移方程

對於狀態 f[i][j],由於我們不能分出空的子陣列,因此合法的狀態必須有 i≥j。對於不合法(i < ji5、f[0][0] 的值初始化為 0

6、最終的答案即為 f[n][m]

**

class

solution

:def

splitarray

(self, nums: list[

int]

, m:

int)

->

int:

#開陣列

n =len(nums)

f =[[

10**18]

*(m +1)

for _ in

range

(n +1)

] sub =[0

]for elem in nums:-1

]+ elem)

#初始化

f[0]

[0]=

0#建立狀態轉移方程

for i in

range(1

, n +1)

:for j in

range(1

,min

(i, m)+1

):for k in

range

(i):

f[i]

[j]=

min(f[i]

[j],

max(f[k]

[j -1]

, sub[i]

- sub[k]))

return f[n]

[m]

時間複雜度:o(n^ 2 ×m),其中 n 是陣列的長度,m 是分成的非空的連續子陣列的個數。

2空間複雜度:o(n×m)

方法二 二分查詢+貪心

貪心地模擬分割的過程,從前到後遍歷陣列,用 sum 表示當前分割子陣列的和,cnt 表示已經分割出的子陣列的數量(包括當前子陣列),那麼每當sum 加上當前值超過了 x,我們就把當前取的值作為新的一段分割子陣列的開頭,並將 cnt 加 1。遍歷結束後驗證是否 \textitcnt 不超過 m。

二分的上界為陣列 nums 中所有元素的和,下界為陣列 nums 中所有元素的最大值。通過二分查詢,我們可以得到最小的最大分割子陣列和,這樣就可以得到最終的答案了。

**

class

solution

:def

splitarray

(self, nums: list[

int]

, m:

int)

->

int:

defcheck

(x:int)-

>

bool

:#用 sum 表示當前分割子陣列的和,cnt 表示已經分割出的子陣列的數量

total, cnt =0,

1for num in nums:

if total + num > x:

cnt +=

1 total = num

else

: total += num

return cnt <= m

#二分的上界為陣列 nums 中所有元素的和,下界為陣列 nums 中所有元素的最大值。

left =

max(nums)

right =

sum(nums)

while left < right:

mid =

(left + right)//2

if check(mid)

: right = mid

else

: left = mid +

1return left

時間複雜度:o(n×log(sum−maxn)),其中 }sum 表示陣列nums 中所有元素的和,maxn 表示陣列所有元素的最大值。

空間複雜度:o(1)。

每日一題 連續子陣列的最大值

用遞迴的方式分析動態規劃問題,但編碼時常常使用迴圈來解決 設定兩個變數 乙個儲存最大值,乙個儲存當前遍歷到i的最大值 用動態規劃,公式見下方 動態規劃 問題 輸入乙個整型陣列,有正數也有負數。陣列中連續幾個數字為乙個子陣列,求所有子陣列的最大值 輸入 最大的子陣列為 輸出 18 created by...

每日一題 力扣 計畫

98 驗證二叉搜尋樹 問題給定乙個二叉樹,判斷其是否是乙個有效的二叉搜尋樹。假設乙個二叉搜尋樹具有如下特徵 1.節點的左子樹只包含小於當前節點的數。2.節點的右子樹只包含大於當前節點的數。3.所有左子樹和右子樹自身必須也是二叉搜尋樹。示例 1 輸入 2 1 3 輸出 true示例2 輸入 5 1 4...

力扣每日一題 6 14

1300 轉變陣列後最接近目標值的陣列和 給你乙個整數陣列 arr 和乙個目標值 target 請你返回乙個整數 value 使得將陣列中所有大於 value 的值變成 value 後,陣列的和最接近 target 最接近表示兩者之差的絕對值最小 如果有多種使得和最接近 target 的方案,請你返...