题意整理
- 有m辆货车,每辆货车能运送若干个鸡蛋。
- 总共要运送n个鸡蛋。
- 如果货车装不下,可以使用魔法将某辆货车容量翻倍,问最少需要使用多少次魔法,才能一次运完所有鸡蛋。
方法一(排序+贪心)
1.解题思路
首先对x数组进行排序,获得容量最大的货车。然后计算还剩多少鸡蛋运不走,每次选择容量最大的货车施加魔法,剩下的鸡蛋就会最大程度地减少,当没有鸡蛋剩下时,就不用施加魔法了。
2.代码实现
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 * @param m int整型 * @param x int整型一维数组 * @return int整型 */ public int Holy (int n, int m, int[] x) { //排序 Arrays.sort(x); //获取最大值 int max=x[m-1]; //看还剩下多少鸡蛋运不走 for(int i=0;i<m;i++){ n-=x[i]; } int cnt=0; while(n>0){ //每使用一次魔法,就会多运走max*(1<<cnt)的鸡蛋 n-=max*(1<<cnt); cnt++; } return cnt; } }
3.复杂度分析
- 时间复杂度:假设剩下的鸡蛋数为m,货车的最大容量为max,那么总共需要施加 次魔法,时间复杂度是,如果算上排序,则时间复杂度是。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度是。
方法二(贪心)
1.解题思路
首先遍历x数组,计算所有货车总容量sum以及最大货车容量max,当sum小于n时,说明有鸡蛋运不走,需要施加魔法。每次选择容量最大的货车施加魔法,每使用一次魔法,就会多运走的鸡蛋
动图展示:
2.代码实现
import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param n int整型 * @param m int整型 * @param x int整型一维数组 * @return int整型 */ public int Holy (int n, int m, int[] x) { //遍历数组,计算最大值以及累加和 int max=-1,sum=0; for(int i=0;i<m;i++){ max=Math.max(x[i],max); sum+=x[i]; } int cnt=0; //如果所有货车容量之和小于n,则施加魔法 while(sum<n){ //每使用一次魔法,就会多运走max*(1<<cnt)的鸡蛋 sum+=max*(1<<cnt); cnt++; } return cnt; } }
3.复杂度分析
- 时间复杂度:假设所有货车容量总和为sum,货车的最大容量为max,需要运走n个鸡蛋,那么总共需要施加 次魔法,施加魔法前,需要遍历x数组,所以时间复杂度是 。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度是。