leetcode 二分練習第一天

2021-10-05 12:34:25 字數 2155 閱讀 2143

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

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

1 ≤ n ≤ 1000

1 ≤ m ≤ min(50, n)

在輸入:

nums =[7

,2,5

,10,8

]m =

2輸出:

18解釋:

一共有四種方法將nums分割為2個子陣列。

其中最好的方式是將其分為[7,

2,5] 和 [10,

8],因為此時這兩個子陣列各自的和的最大值為18,在所有情況中最小。

參考:

參考**

二分法nums = [7,2,5,10,8]

m = 1,那麼整個陣列作為一部分,最小的最大值為 32

m = n,那麼每個元素作為乙個子陣列,從所有元素選取最大值,最小的最大值小為 10

m 的取值範圍為 1 <= m <= n,因此,最大值的最小值的範圍為 [10, 32]

我們利用二分法查詢,找出符合 m 的最大值的最小的結果

二分過程:

left = 10;

right = 32

mid = (left + right) >>> 1 = 21(這個 21 就是乙個子陣列的最大容量)

我們假設剛開闢的用來儲存的子陣列個數 cnt = 1

那麼根據貪心思想,我們將陣列元素按順序逐個往裡放

因此就有如下過程:

7 < 21

7 + 2 < 21

7 + 2 + 5 < 21

7 + 2 + 5 + 10 > 21

至此,我們可以看出乙個 21 容量的子陣列是無法容納整個陣列元素的,因此我們需要開闢第二個子陣列來儲存剩下的陣列元素

cnt = cnt + 1 = 2

10 < 21

10 + 8 < 21

我們發現,兩個子陣列可以將整個陣列元素放入,而 cnt 剛好等於 m,因此 [7,2,5] 和 [10,8] 就是分割出來的兩個子陣列,最小的最大值為 18

為什麼是放入元素直到放不下為止?因為要求的是連續子陣列,我們需要保證每個連續的子陣列的元素和都盡可能的接近 21

如果我們最終得到的 cnt > m,那麼表示我們劃分出太多的子陣列,也就是意味著乙個子陣列的容量太少,我們需要再擴大容量,即 left = mid + 1,然後繼續進行二分

如果我們最終得到的 cnt < m,那麼表示我們劃分出太少的子陣列,也就是意味著乙個子陣列的容量太大,需要減少容量,即 right = mid - 1

*/

用乙個例子來分析,nums = [1, 2, 3, 4, 5], m = 3,將 left 設為陣列中的最大值5,right 設為數字之和 15,然後算出中間數為 10,接下來要做的是找出和最大且小於等於 10 的子陣列的個數,[1, 2, 3, 4], [5],可以看到無法分為3組,說明 mid 偏大,所以讓 right=mid,然後再次進行二分查詢,算出 mid=7,再次找出和最大且小於等於7的子陣列的個數,[1,2,3], [4], [5],成功的找出了三組,說明 mid 還可以進一步降低,讓 right=mid,再次進行二分查詢,算出 mid=6,再次找出和最大且小於等於6的子陣列的個數,[1,2,3], [4], [5],成功的找出了三組,嘗試著繼續降低 mid,讓 right=mid,再次進行二分查詢,算出 mid=5,再次找出和最大且小於等於5的子陣列的個數,[1,2], [3], [4], [5],發現有4組,此時的 mid 太小了,應該增大 mid,讓 left=mid+1,此時 left=6,right=5,迴圈退出了,返回 right 即可,參見**如下

*/

class

solution

// 退出條件 在切分的陣列等於m 的情況下 盡可能的 縮小最小值

while

(leftreturn left;

}bool

can(vector<

int>

&nums,

int m,

int mid)

}// cnt <= m mid 選打了 =m 時代表還能繼續切分 繼續求小值

return

true;}

};

演算法練習 第一天

求1 1!1 3!1 5!1 7!1 n 1 2n 1 下面的演算法時間複雜度為o n 2 public class leijia leicheng sum sum sign a system.out.println sign a system.out.println 結果是 sum 求1 1!1 ...

python第一天練習

1.有四個數字 1 2 3 4,能組成多少個互不相同且無重複數字的三位數?各是多少?for i in range 1,5 for j in range 1,5 for k in range 1,5 if i k and i j and j k print i,j,k 2.利用條件運算子的巢狀來完成此...

python練習 第一天

from math import sqrt class point object 描述平面上的點 def init self,x,y param x 橫座標 param y 縱座標 self.x x self.y y defmove to self,x,y 移動到某點的方法 param x 目標點的...