leetcode 队列习题

最近的请求次数

写一个 RecentCounter 类来计算最近的请求。

它只有一个方法:ping(int t),其中 t 代表以毫秒为单位的某个时间。

返回从 3000 毫秒前到现在的 ping 数。

任何处于 [t - 3000, t] 时间范围之内的 ping 都将会被计算在内,包括当前(指 t 时刻)的 ping。

保证每次对 ping 的调用都使用比之前更大的 t 值。

输入:inputs = [“RecentCounter”,“ping”,“ping”,“ping”,“ping”], inputs = [[],[1],[100],[3001],[3002]]
输出:[null,1,2,3,3]

解题思路(参考题解)

计算t时刻之前的ping值在 [t - 3000, t] 时间范围之内的个数

1的话,区间为[-2999,1]有一个(1),100:[-2900,100]有两个(1,100).。。。。

注意:每次对 ping 的调用都使用比之前更大的 t 值。只需要看队列前面的数是否比t-3000小

代码
class RecentCounter {
public:
    queue<int> q;
    RecentCounter() {

    }

    int ping(int t) {
        //保证每次对 ping 的调用都使用比之前更大的 t 值
        q.push(t);
        //只要队列前面的数小于t-3000就出队,如果出现比它大的就证明后面的数都比t-3000大
        while(!q.empty())
        {
            if(q.front()<t-3000)
                q.pop();
            else
                break;
        }
        return q.size();
    }
};
剑指 Offer 59 - I. 滑动窗口的最大值

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3
输出: [3,3,5,5,6,7]
解释:

滑动窗口的位置 最大值


[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7

解题思路

暴力解法,自己写的垃圾解法

vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ma;
        int max;
        for(vector<int>::iterator it=nums.begin();it!=nums.end();it++)
        {
            max=*it;
            for(int i=0;i<k;i++)
            {
                if(it==nums.end()) break;
                if(*it>max) max=*it;
                it++;
            }
            ma.push_back(max);
            if(it==nums.end()) break;
            it-=k;

        }
        return ma;
    }
int main()
{
    vector<int> nums;
    vector<int> n;
    int k,temp;
    for(int i=0;i<8;i++)
    {
        cin>>temp;
        nums.push_back(temp);
    }
    cin>>k;
    n=maxSlidingWindow(nums,k);
    for(vector<int>::iterator it=n.begin();it!=n.end();it++)
    {
        cout<<*it<<" ";
    }
    return 0;
}
参考题解
vector<int> maxSlidingWindow(vector<int>& nums, int k)
{
    vector<int> ans;
    int n=nums.size();
    //数组没有元素时
    if(!n) return ans;
    //队列存储下标,单调递减
    deque<int> d;//定义一个双端队列,前面后面都可以push和pop
    for(int i=0;i<n;i++)
    {
        //当队列不为空,单调队列的最小值小于数组中的元素时
        //队列中只保存数组最大值的下标
        while(!d.empty()&&nums[i]>=nums[d.back()])
            d.pop_back();
        //删除无效的索引,即超出滑动窗口最前面的下标
        while(!d.empty()&&d.front()<i-k+1)
            d.pop_front();
        d.push_back(i);
        //将每次数组中的最大值push进输出数组
        if(i>=k-1) ans.push_back(nums[d.front]);
    }
    return ans;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值