933. 最近的请求次数
先上题目
一段C++代码
class RecentCounter {
public:
queue<int>que;
int ans;
RecentCounter() {
ans = 0;
}
int ping(int t) {
que.push(t);
ans++;
while(t - que.front() > 3000){
que.pop();
ans--;
}
return ans;
}
};
#return q.size();
/**
* Your RecentCounter object will be instantiated and called as such:
* RecentCounter* obj = new RecentCounter();
* int param_1 = obj->ping(t);
*/
时间复杂度:均摊 O(1),每个元素至多入队出队各一次。
空间复杂度:O(L),其中 L 为队列的最大元素个数。
越做越觉得C++来写力扣太爽了,C++才是世界排名第二的语言(第一是python,猥琐笑.jpg)
做个简单的解释
1. 首先是对于队列的声明工作,queue<int>que。
2. int一个全局变量请求数。
3. 这个是用队列实现的一个查询工作,当想入队列,就que.push(t),即可。
4. 当想出队列时,就que.pop()。
5. 每次来一个请求就自动请求数加一,然后有请求超出时间就将他pop出来
,然后将请求数减一,用while循环进行pop。
换一个别的答题方式,还是C++,就是用数组实现的(其实没什么大不了的,就是多看看别的解题形式呗,hhhh)
这个方法看起来是个笨蛋解法
class RecentCounter {
public:
int left, right, times[10005];
RecentCounter() {
left = 0, right = 0;
}
int ping(int t) {
times[right++] = t;
while (times[left] < t - 3000) {
left++;
}
return right - left;
}
};
类似于双指针
class RecentCounter {
private:
int a[10007] = {0};
int pt = 0;
int pc = 0;
public:
RecentCounter() {
}
int ping(int t) {
a[pc] = t;
while (a[pc] - a[pt] > 3000)
pt++;
pc++;
return pc - pt;
}
};
1. times[right++] = t;
这句操作就是,先进行存储,在进行加的操作
我觉得不管哪个操作,就是灵活的运用队列的操作是关键
评论区有一句话展现了这个方法的巧妙之处
“oi常见奇技淫巧,CPU cache数是2的幂,N + 5是一个奇数,
与之互素,这样可以减少cache冲突概率,提高速度。”
“不过一维数组就没必要用这个技巧了,对于多维数组是有用的。”
这个方法是利用二分法
class RecentCounter {
private:
vector<pair<int, int>> arr;
int cnt = 0;
public:
RecentCounter() {
}
int ping(int t) {
int target = t - 3000;
cnt++;
arr.push_back({t, cnt});
pair<int, int> tmp = {target, -1};
auto it = lower_bound(arr.begin(), arr.end(), tmp);
tmp = *it;
return cnt - tmp.second + 1;
}
};
来个C语言的
typedef struct {
int *queue;
int capability;
int head;
int tail;
} RecentCounter;
RecentCounter* recentCounterCreate() {
RecentCounter *obj = (RecentCounter *)malloc(sizeof(RecentCounter));
obj->capability = 10001;
obj->queue = (int *)malloc(sizeof(int) * obj->capability);
obj->head = 0;
obj->tail = 0;
return obj;
}
int recentCounterPing(RecentCounter* obj, int t) {
obj->queue[obj->tail++] = t;
while (obj->queue[obj->head] < t - 3000) {
obj->head++;
}
return obj->tail - obj->head;
}
void recentCounterFree(RecentCounter* obj) {
free(obj->queue);
free(obj);
}
python的整上
class RecentCounter:
def __init__(self):
self.q = deque()
def ping(self, t: int) -> int:
self.q.append(t)
while self.q[0] < t - 3000:
self.q.popleft()
return len(self.q)
1. python的双向队列
Python的deque()——双向队列
Python中的标准库collections中有一个deque,该对象与list列表相似。
这里的“双向”指的是deuqe的结构使用双向链表,它提供了两端都可以
操作的序列,这意味着,我们可以在序列前后都执行添加或删除。大
多操作与List相同,如访问元素,求序列长度等,同样deque序列中的
元素类型也不唯一。
2.
关于deque的相关知识链接: link