1894. 找到需要补充粉笔的学生编号

1894. 找到需要补充粉笔的学生编号

贴个题目:

题目

贴个示例:

示例

解题思路:

方法一:一次遍历+模拟

读完题目我们可以看出,其实就是循环派粉笔给学生,直到学生拿不到足够的粉笔,这时候就返回学生的位置。

那么我们可以先求循环一次学生需要多少支粉笔,然后求出派到最后一轮的时候,剩余的粉笔数。

最后就遍历一次数组,一边遍历,一边减少粉笔数,什么时候粉笔数是负数的时候,就证明这一个学生不够粉笔派了,此时返回这一个学生的下标即可。

优化:

我们可以通过取余数来求出最后一轮的时候剩余的粉笔数,这样子也能避免数据溢出

accumulate()函数是C++中的求和函数,详情可以看介绍:C++STL中的求和函数accumulate()

方法一代码:
class Solution {
public:
    int chalkReplacer(vector<int>& chalk, int k) {
        //accumulate(_InIt _First, _InIt _Last, _Ty _Val)求和函数
        //因为sum是long long类型,因此最后一个参数是0LL而不是0
        long long sum=accumulate(chalk.begin(),chalk.end(),0LL);
        //求出最后一轮剩余的粉笔数量
        int reminder=k%sum;
        int index=-1;
        //求出不够派的学生位置
        while(reminder>=0) reminder-=chalk[++index];
        return index;
    }
};
方法一性能分析:
时间分析:

一次遍历数组,因此时间复杂度是:O(n)

空间分析:

新建了常数个变量,因此空间复杂度是:O(1)

方法二:前缀和+二分查找

仔细阅读题目之后我们可以发现,其实求在最后一次派粉笔的时候,要求派的前n个同学的粉笔数大于k,此时就返回n这个校标即可。

那么根据以上的思路,我们可以使用前缀和求出前n个同学的粉笔数,然后在查找k的位置的时候,由于前缀和数组是递增数组,因此可以使用二分查找算法。

upper_bound()是C++中的二分查找函数,详细可以查看以下链接:C++STL中的upper_bound()函数的使用

方法二代码:
class Solution {
public:
    int chalkReplacer(vector<int>& chalk, int k) {
        if(chalk.front()>k) return 0;//特殊情况
        //前缀和
        for(int i=1;i<chalk.size();i++)
        {
            chalk[i]+=chalk[i-1];
            if(chalk[i]>k) return i;
        }
        k%=chalk.back();//取余数,减少k的大小
        //二分查找函数upper_bound,寻找大于k的数
        return upper_bound(chalk.begin(),chalk.end(),k)-chalk.begin();
    }
};
方法二性能分析:
时间分析:

前缀和时间复杂度是:O(n),二分查找的时间复杂度是:O(logn),因此总的时间复杂度是取其最大值,为:O(n)

空间分析:

新建了常数个变量,因此空间复杂度是:O(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值