牛牛打怪题解
30分解法
首先将防御力排个序。我们把防御力最高的怪防御力视为m,答案可以从m向上while(1)暴力判断每一个答案是否合法,循环次数最多n-1次,每次判断合法最多n次,时间复杂度o(n^2),空间复杂度o(1)。
100分解法
解法1:dp
首先将防御力排个序,第一只怪最少要在在第DEF[0]天杀死,而第二只怪最少要在在 "图片标题") ,所以只需要递推
"图片标题") 然后输出dp[n-1]即可。dp的时间复杂度o(n),排序的时间复杂度o(nlogn),所以总体时间复杂度o(nlogn),空间复杂度o(n)
代码:
int dp[1000005];
class Solution {
public:
/**
*
* @param n int整型
* @param DEF int整型vector
* @return int整型
*/
int Minimumdays(int n, vector<int>& DEF) {
// write code here
sort(DEF.begin(),DEF.end());
dp[0]=DEF[0];
for(int i=1;i<DEF.size();i++)
{
dp[i]=max(dp[i-1]+1,DEF[i]);
}
return dp[n-1];
}
};解法2:二分
还是首先先将数组排序,我们可以二分答案天数,下限是DEF[i]的最大值,上限是DEF[i]的最大值+n-1,所以二分的时间复杂度为o(logn),假设每次二分值为mid,每次判断对于DEF最大值是否小于等于mid,在判断次大值是否满足小于等于mid-1,都满足了就是可行,有一个不满足就是不可行。以此类推,每次判断的时间复杂度为o(n)。所以整体的时间复杂度为o(nlogn),空间复杂度为o(n)。
代码:
class Solution {
public:
/**
*
* @param n int整型
* @param DEF int整型vector
* @return int整型
*/
int Minimumdays(int n, vector<int>& DEF) {
// write code here
sort(DEF.begin(),DEF.end());
int l=DEF[n-1],r=DEF[n-1]+n-1,mid,pos;
while(l<=r)
{
mid=(l+r)/2;
int ATK=mid;
int flag=1;
for(int i=n-1;i>=0;i--)
{
if(DEF[i]>ATK){flag=0;break;}
ATK--;
}
if(flag){pos=mid;r=mid-1;}
else l=mid+1;
}
return pos;
}
};