There are n projects numbered from 0 to n - 1. You are given an integer array milestones where each milestones[i] denotes the number of milestones the ith project has.
You can work on the projects following these two rules:
Every week, you will finish exactly one milestone of one project. You must work every week.
You cannot work on two milestones from the same project for two consecutive weeks.
Once all the milestones of all the projects are finished, or if the only milestones that you can work on will cause you to violate the above rules, you will stop working. Note that you may not be able to finish every project's milestones due to these constraints.
Return the maximum number of weeks you would be able to work on the projects without violating the rules mentioned above.
Example 1:
Input: milestones = [1,2,3]
Output: 6
Explanation: One possible scenario is:
- During the 1st week, you will work on a milestone of project 0.
- During the 2nd week, you will work on a milestone of project 2.
- During the 3rd week, you will work on a milestone of project 1.
- During the 4th week, you will work on a milestone of project 2.
- During the 5th week, you will work on a milestone of project 1.
- During the 6th week, you will work on a milestone of project 2.
The total number of weeks is 6.
Example 2:
Input: milestones = [5,2,1]
Output: 7
Explanation: One possible scenario is:
- During the 1st week, you will work on a milestone of project 0.
- During the 2nd week, you will work on a milestone of project 1.
- During the 3rd week, you will work on a milestone of project 0.
- During the 4th week, you will work on a milestone of project 1.
- During the 5th week, you will work on a milestone of project 0.
- During the 6th week, you will work on a milestone of project 2.
- During the 7th week, you will work on a milestone of project 0.
The total number of weeks is 7.
Note that you cannot work on the last milestone of project 0 on 8th week because it would violate the rules.
Thus, one milestone in project 0 will remain unfinished.
Constraints:
n == milestones.length
1 <= n <= 105
1 <= milestones[i] <= 109
你可以工作的最大週數。
給你 n 個專案,編號從 0 到 n - 1 。同時給你一個整數陣列 milestones ,其中每個 milestones[i] 表示第 i 個專案中的階段任務數量。你可以按下面兩個規則參與專案中的工作:
- 每週,你將會完成 某一個 專案中的 恰好一個 階段任務。你每週都 必須 工作。
- 在 連續的 兩週中,你 不能 參與並完成同一個專案中的兩個階段任務。
一旦所有專案中的全部階段任務都完成,或者僅剩餘一個階段任務都會導致你違反上面的規則,那麼你將 停止工作 。注意,由於這些條件的限制,你可能無法完成所有階段任務。
返回在不違反上面規則的情況下你 最多 能工作多少周。
思路
思路是貪心。題目要求我們儘可能多地完成任務且每兩個連續的任務不能是同樣的。為了儘可能多地完成任務,一個不難想到的思路是我們能否先找到任務量最多的任務,如果我們能完成這個任務量最多的任務,那麼我們不就可以把剩下的任務穿插在這個最多的任務中間了嗎?這樣也滿足題目不能連續兩週做同一個任務的要求。
想到這個思路不難,這裡我們說明一下這個思路的可行性。我們遍歷一遍 input 陣列,找到任務數量最多的任務,記為 longest。同時我們累加每一個任務,把全域性所有任務數量的總和記為 sum,那麼除 longest 之外的其他任務的數量 rest = sum - longest。假設我們能跑完 longest 的所有任務,那麼我們至少需要 rest >= longest - 1。舉例,比如 longest = 10,那麼我們要讓 rest 不小於 9 才行,因為 10 個任務中間有 9 個空隙可以插進去。
因此,當我們找到 longest 之後,我們可以直接判斷,如果 rest >= longest - 1,那麼可以完成所有任務;反之如果不滿足這個條件,那麼我們只能滿足 2 * rest + 1 個任務。在剩下的 rest 個任務中間插入 rest + 1 個最多型別的任務。
複雜度
時間O(n)
空間O(1)
程式碼
Java實現
class Solution {
public long numberOfWeeks(int[] milestones) {
long longest = milestones[0];
long sum = 0;
for (int milestone : milestones) {
longest = Math.max(longest, milestone);
sum += milestone;
}
long rest = sum - longest;
if (rest < longest - 1) {
return rest * 2 + 1;
}
return sum;
}
}