382.小C不怕困难 题解及思路
382.小C不怕困难
问题描述
小C遇到了 个怪物,第 i 个怪物的战斗力为 ,而小C的初始战斗力为 。他需要依次与这些怪物战斗。战斗时的规则如下:
- 如果小C的战斗力 小于怪物的战斗力 ,小C会触发被动技能 "小C不怕困难",将自己的战斗力提升至 ,并战胜这个怪物,同时小C的勇气值增加 。
- 如果小C的战斗力 大于或等于怪物的战斗力 ,他会直接战胜这个怪物,战斗结束后,小C的战斗力会降低至 。 小C可以自由决定与怪物战斗的顺序。他想知道,在打败所有怪物后,自己能够累计提升的勇气值最大是多少。
示例1:
输入:n = 2 ,a = [1, 2]
输出:2
解释: 观察a
数组,令x = 0
,先取最大值a[1] = 2
,战斗力增加为2
,勇气增加2-0 =2
,再寻找a[0] = 1
,不增加勇气
示例2:
输入:n = 3 ,a = [1, 2, 2]
输出:3
解释: 观察a
数组,令x = 0
,先取最大值a[2] = 2
,勇气增加2-0 =2
,再寻找a[0] = 1
,不增加勇气,战斗力降低至1
.再选取a[1] = 2
,勇气为2 +(2-1)=3
,战斗力增加至2
示例3:
输入:n = 4 ,a = [3, 6, 2, 8]
输出:12
解释: 观察a
数组,令x = 0
,先取最大值a[3] = 2
,勇气增加8-0 =8
,再寻找a[2] = 2
,不增加勇气,战斗力降低至2
.再选取a[1] = 6
,勇气为8 +(6-2)=12
,战斗力增加至6
解题思路
思路1
暴力递归,遍历每种可能,返回其中的最大值,递归结束条件为遍历完所有怪物, 递归过程中依照题目条件进行判断如何操作,将操作后的状态进入下个递归,递归结束后完成状态的回退(或保存操作前的状态)
提示 本题暴力递归无法正确提交(超时),时间复杂度为O(),故不给出代码.
思路2
双指针思路
观察发现当我们一开始x = 0
时选取a
中最大值可以保证得到单次操作中最多的勇气值(贪),勇气值为最大值减去当前的战斗力
观察发现,接下来的两次操作只要我们选取a
的最小值,再选取a
的最大值,两者之差即为这两次操作后增加的勇气值
所以对于a,我们只需排序后将最大值作为首次操作增加的勇气值,再将左指针left=0
和右指针right
之差的结果作为接下来两次操作可增加的最大勇气值即可。
java代码
public static int solution(int n, int[] a) {
Arrays.sort(a);
int courage =a[n-1];
int left =0;
int right=n-2;
while (left<right){
courage += a[right]-a[left];
left++;
right--;
}
return courage;
}