力扣刷题日记 798. 得分最高的最小轮调

798. 得分最高的最小轮调

题目描述

在这里插入图片描述

题解思路

数据范围没有截图到,这里的数据范围为0-20000
题目的内容还是很好理解的,就是给你一个数组,你可以将数组内容向左推移若干次,而我们定义如果数组当前位置的值小于其索引即可得分,求使得得分最大的那个推移次数。
首先,单从模拟的思路来说,我们很容易想到的一点是我们直接暴力来枚举所以的n的次数,然后再求每个次数的分数,但是可惜的是,这个算法的时间复杂度为O(n2),因为最高的数据可以到20000,显然会TLE
由于这个数据范围,我们就得重新来审视题目了,很明显的一点是,对于任意的一个数值,他都有自己的独有的得分区域,例如在长度为7(索引范围为0-6)的数组中,有一个值为5,那么如果我们要得到这个值的点数,则一定要让这个值位于索引[5,6]间,那么[5-6]就是这个值的得分区域,而[0,4]就不是他的得分区域,那么,我们只需要求出值在第几次移动时进入得分区域,那么这个推动的范围就是得分范围。
那么此时,我们的任务就变成了找到最大的重合数,找到重合最多次数的推动范围,我们就可以得到最高的分数,而进入这个范围的那个值则为我们所需要的k值。
而这又该怎么解决呢?前缀和!!!
前缀和算是算法中常用的一种方法了,之后我也会写一篇博客来专门梳理一下(给自己梳理一下hhhh)

代码

class Solution {
    public int bestRotation(int[] nums) {
        int k = nums.length;
        int[] turns = new int[k+5];
        for(int i = 0;i<k;i++)
        {
            int num = nums[i];
            if(num>i)//判断值大于初始位置(即初始不得分)
            {
                turns[i+1]++;
                turns[k+1-(num-i)]--;
            }
            else//初始得分情况
            {
                turns[0]++;
                turns[i-num+1]--;
                turns[i+1]++;
            }
        }
        int zhi = 0,mzhi = 0,ansk = 0;
        for(int i = 0;i<k;i++)//前缀和方法
        {
            zhi += turns[i];
            if(zhi > mzhi) 
            {
                mzhi = zhi;
                ansk = i;
            }
        }
        return ansk;
    }
}

结语

如果有想一起每天互相监督刷题的小伙伴可以加上微信,咱们一起加油呀!也可以一起讨论讨论题目

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值