給定乙個非負整數陣列和乙個整數 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 目標點的...