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
milestones 互相消耗, 最终只有 2 种结局:
- 剩余 2 个 projects
- 剩余 3 个 projects
剩余 2 个的话比较好考虑, 如果两者的差值小于 1, 则两者都会消耗完, 其他情况最终会剩余差值-1。如果剩余 3 个的话,我们要记住一条, 两个较小的 milestones 的和如果大于等于最大的 milestones, 那一定是可以消耗完的, 如果小于,那我们可以把两个较小的合并成一个 project, 然后参考剩余 2 个的情况
impl Solution {
pub fn number_of_weeks(mut milestones: Vec<i32>) -> i64 {
match milestones.len() {
1 => return 1,
2 => {
if milestones[0] == milestones[1] {
return milestones[0] as i64 * 2;
}
return milestones[0].min(milestones[1]) as i64 * 2 + 1;
}
_ => {
milestones.sort();
let sum: i64 = milestones.iter().map(|&v| v as i64).sum();
while milestones.len() > 3 {
let left = milestones.remove(0) as i64;
let right = milestones.pop().unwrap() as i64;
if left < right {
milestones.push(right as i32 - left as i32);
continue;
}
if left > right {
milestones.push(left as i32 - right as i32);
continue;
}
}
milestones.sort();
if milestones.len() == 2 {
if milestones[0] == milestones[1] {
return sum;
}
return sum - (milestones[1] - milestones[0] - 1) as i64;
}
if milestones[0] + milestones[1] >= milestones[2] {
return sum;
}
let diff = (milestones[2] - milestones[0] - milestones[1]) as i64;
if diff <= 1 {
return sum;
}
return sum - (diff - 1);
}
}
}
}