简单队列
第一题

int timeRequiredToBuy(int* tickets, int ticketsSize, int k){
int cnt=0;
int i=0;
while(tickets[k]!=0)
{
if(tickets[i]>0)
{
tickets[i]--;
cnt++;
}
i++;
if(i==ticketsSize)
{
i=0;
}
}
return cnt;
}
typedef struct
{
int idx;
int need;
}Queue;
int timeRequiredToBuy(int* tickets, int ticketsSize, int k){
Queue q[50000];//队列,数组存类
Queue temp;
int front=0;
int rear=0;
//将第一批人入队
for(int i=0;i<ticketsSize;i++)
{
q[rear]->idx=i;
q[rear]->need=tickets[i];
rear++;
}
int time=0;
while(front<rear)
{
Queue temp=q[front];
front++;
temp->need--;
time++;
if(temp->need)
{
q[rear++]=temp;//重新入队
}
else{
if(temp->idx==k)
{
return time;
}
}
}
return 0;
}
q[rear++]=temp;让其重新入队
滑动窗口
第一题

struct Data {
int time; // (1)
};
/**************************** 链表 实现队列 ****************************/
#define DataType struct Data
#define maxn 100005
struct QueueNode;
struct QueueNode {
DataType data;
struct QueueNode *next;
};
struct Queue {
struct QueueNode *head, *tail;
int size;
};
void QueueEnqueue(struct Queue *que, DataType dt) {
struct QueueNode *insertNode = (struct QueueNode *) malloc( sizeof(struct QueueNode) );
insertNode->data = dt;
insertNode->next = NULL;
if(que->tail) {
que->tail->next = insertNode;
que->tail = insertNode;
}else {
que->head = que->tail = insertNode;
}
++que->size;
}
void QueueDequeue(struct Queue* que) {
struct QueueNode *delNode = que->head;
que->head = delNode->next;
free(delNode);
--que->size;
}
DataType QueueGetFront(struct Queue* que) {
return que->head->data;
}
int QueueGetSize(struct Queue* que) {
return que->size;
}
int QueueIsEmpty(struct Queue* que) {
return !QueueGetSize(que);
}
void QueueClear(struct Queue* que) {
que->head = que->tail = NULL;
que->size = 0;
}
队列用链表实现模板
typedef struct {
struct Queue q;//是一个队列
} RecentCounter;
RecentCounter* recentCounterCreate() {
RecentCounter*ret=(RecentCounter*)malloc(sizeof(RecentCounter));
QueueClear(&ret->q);
return ret;
}
int recentCounterPing(RecentCounter* obj, int t) {
DataType dt;//当前信息
DataType front;
dt.time=t;
//设置一个指向队列的指针,来做传参
struct Queue*temp=&obj->q;
QueueEnqueue(temp,dt);//将当前元素入队
while(!QueueIsEmpty(temp))//当队列不空
{
front=QueueGetFront(temp);
if(dt.time-front.time>3000)
{
QueueDequeue(temp);
}
else{
break;
}
}
return QueueGetSize(temp);
}
void recentCounterFree(RecentCounter* obj) {
free(obj);
}
注意:
struct Queue*temp=&obj->q;
此处要加&,是因为要用temp代替obj->q的地址,因为调用函数时都有*
第二题

将sum构筑于结构体中,每次加入元素就+=
MovingAverage* movingAverageCreate(int size) {
MovingAverage*ret=(MovingAverage*)malloc(sizeof(MovingAverage));
QueueClear(&ret->q);
ret->ssize=size;
ret->sum=0;
return ret;
}
double movingAverageNext(MovingAverage* obj, int val) {
DataType dt;//当前元素
dt.num=val;
obj->sum+=val;
struct Queue*temp=&obj->q;
QueueEnqueue(temp,dt);
double qsize=QueueGetSize(temp);
while(qsize>obj->ssize)
{
DataType front=QueueGetFront(temp);
obj->sum-=front.num;
QueueDequeue(temp);//让队首的出去
qsize--;
}
return obj->sum/QueueGetSize(temp);
}
void movingAverageFree(MovingAverage* obj) {
free(obj);
}
这篇博客探讨了如何使用简单队列和滑动窗口解决两个实际问题。第一部分展示了如何通过队列计算购票所需时间,而第二部分则介绍了如何利用滑动窗口计算最近3000毫秒内的请求数量,以及如何实现移动平均值的计算。博客还提供了链表实现队列的代码模板,并讲解了结构体和指针的使用。
658

被折叠的 条评论
为什么被折叠?



