从魔法师身上吸取的最大能量

 题目

在神秘的地牢中,n 个魔法师站成一排。每个魔法师都拥有一个属性,这个属性可以给你提供能量。有些魔法师可能会给你负能量,即从你身上吸取能量。

你被施加了一种诅咒,当你从魔法师 i 处吸收能量后,你将被立即传送到魔法师 (i + k) 处。这一过程将重复进行,直到你到达一个不存在 (i + k) 的魔法师为止。

换句话说,你将选择一个起点,然后以 k 为间隔跳跃,直到到达魔法师序列的末端,在过程中吸收所有的能量。

给定一个数组 energy 和一个整数k,返回你能获得的 最大 能量。

示例 1:

输入: energy = [5,2,-10,-5,1], k = 3

输出: 3

解释:可以从魔法师 1 开始,吸收能量 2 + 1 = 3。

示例 2:

输入: energy = [-2,-3,-1], k = 2

输出: -1

解释:可以从魔法师 2 开始,吸收能量 -1。

链接

100274. 从魔法师身上吸取的最大能量 - 力扣(LeetCode)第 397 场周赛 - 力扣(LeetCode)

解题思路

这一道题相当于是从数组中的某一个元素开始,依次间隔k的元素,到结束的和的最大值,首先来看暴力解法,两个for循环,外层for循环遍历所有元素,内层for循环累加间隔k的和,但是这样会超时,接着来看看优化,比如说这个用例energy = [5,2,-10,-5,1], k = 2,从5开始,5+(-10)+(1),2+(-5),(-10)+1,-5,1,这是暴力解法的情况,我们会发现从(-10)开始算的话其实就已经重复了,因为在第一次算的时候就已经算过了,知道这里就可以进行优化了,5+(-10)是大于(-10)的,也就是说如果我们再次算到(-10)的时候其实就已经不用算了,因为要求出来的是最大值,前面的累加已经使结果大于自己了,再从自己算,不就变小了吗。如果他是小于的,那么我们就没必要要前面的值。

还是以这个为例,energy = [5,2,-10,-5,1], k = 2.我们新取一个数组arr[7],让第一个元素设置为0,即arr[0]=0,如果下标超出数组长度了就不需要累加,当下标小于等于k时,我们让前k个元素直接进行一次累加,接着arr[1]=5+(-10)=-5,arr[2]=2+(-5)=-3,,当下标大于k时,就开始重复了,此时判断arr[3]是否需要在arr[3-k]的基础上进行累加,如果arr[3-k]小于arr[3]的话,就不需要,否则就需要,那么arr[3]=arr[1]+1=-4,后面同理判断,arr[4] = arr[2] = -3(此时下标已经越界了,就不需要找下一个间隔为k的元素了),arr[5] = 1。

再来看个长一点的用例,energy =[5,-10,4,3,5,-9,9,-7,4],k =2,arr[10]。

下标小于等于k

arr[1] = energy[0] + energy[0+k] = 9,

arr[2] = energy[1] + energy[1+k] = -7,

下标大于k

arr[3] = arr[1] + energy[2+k] = 14,

arr[4] = energy[3] + energy[3+k] = -6;

arr[5] = arr[3] + energy[4+k] = 23,

arr[6] = arr[4] + energy[5+k] = -13,

arr[7] = arr[5] + energy[6+k] = 27,

arr[8] = energy[7] = -7,

arr[9] = arr[7] = 27.

此时最后k个元素比较就是我们要的值了。

注意一个小细节就是数组不要越界

下面是ac代码

class Solution {
public:
    int maximumEnergy(vector<int>& energy, int k) {
        int ret = INT_MIN,n = energy.size();
        vector<int> v(n+1,0);
        for(int i = 1;i<n+1;i++)
        {
            if(i<=k)
            {
                if(i-1+k<n)
                v[i] = energy[i-1]+energy[i-1+k];
                else
                v[i] = energy[i-1];
            }
            else
            {
                int tmp = v[i-k]>energy[i-1]?v[i-k]:energy[i-1];
                if(i-1+k<n)
                v[i] = tmp + energy[i-1+k];
                else
                v[i] = tmp;
            }
            if(i>n-k) ret = max(ret,v[i]);
        }

        return ret;
    }
};

  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值