双端队列实现滚动窗口最大值
本文最后更新于567 天前,其中的信息可能已经过时,如有错误请发送邮件到1986413837@qq.com

基本表现形式如下

利用双端队列 保证队列内部递减 队首元素即为最大值

C语言确实比C++麻烦不少 源代码如下

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
//结点结构体
typedef struct Node 
{
	int value;
	struct Node* next;
}Node;
//双端队列结构体
typedef struct MyQueue
{
	Node* front;
	Node* rear;
}MyQueue;
//初始化双端队列
MyQueue* creatQueue()
{
	MyQueue* Queue=(MyQueue*)malloc(sizeof(MyQueue));
	Queue->rear = NULL;
	Queue->front = NULL;
	return Queue;
}
//放置结点在队尾(保证递减!)
void Push(MyQueue* queue, int val)
{
	Node* newNode = (Node*)malloc(sizeof(Node));
	newNode->value = val;
	newNode->next = NULL;

	if (queue->rear == NULL)
	{
		queue->rear = newNode;
		queue->front = newNode;
	}
	else
	{
		queue->rear->next = newNode;
		queue->rear = newNode;
	}

	Node* curr = queue->front;
	Node* prev = NULL;
	while (curr != NULL && curr->value < val)
	{
		Node* temp = curr;    // 存储当前节点以便稍后释放内存
		curr = curr->next;    // 移动到下一个节点
		free(temp);           // 释放当前节点的内存
		if (prev == NULL)     // 如果这是第一个节点
			queue->front = curr; // 更新队列的前端
		else
			prev->next = curr; // 将前一个节点链接到当前节点
	}
	if (curr == NULL)queue->rear = prev;   // 如果 curr 为 NULL,更新队列的后端
}
//删除旧框结点
void Pop(MyQueue* queue,int val)
{
	if (queue->front != NULL && queue->front->value == val)
	{
		Node* temp = queue->front;
		queue->front = queue->front->next;
		if (queue->front == NULL)queue->rear = NULL;
		free(temp);
	}
}
//获取最大元素
int front(MyQueue* queue)
{
	return (queue->front != NULL) ? queue->front->value : -1;
}
//清空队列
void freeQueue(MyQueue* queue)
{
	Node* curr = queue->front;
	while (curr!=NULL)
	{
		Node* temp = curr;
		curr = curr->next;
		free(temp);
	}
	free(queue);
}
//获得窗口最大值数组
//用returnSize直接获取目标数组大小 很方便
int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize)
{
	MyQueue* que = creatQueue();
	//n元素 k大小的框 一共会出现n-k+1个窗口
	int* res = (int*)malloc((numsSize - k + 1) * sizeof(int));
	*returnSize = 0;
	int left = 0, right = 0;
	//初始化一下前面的k个组成的窗口
	while (right < k)
	{
		Push(que, nums[right++]);
	}
	res[(*returnSize)++] = front(que);
	//这之后左边界移动 删除旧窗口元素
	while (right<numsSize)
	{
		Push(que, nums[right++]);
		Pop(que, nums[left++]);
		res[(*returnSize)++] = front(que);
	}
	freeQueue(que);
	return res;
}
int main()
{
	int nums[] = { 1,3,-1,-3,5,3,6,7 };
	int k = 3;
	int returnSize;
	int* result = maxSlidingWindow(nums, sizeof(nums) / sizeof(nums[0]), k, &returnSize);
	for (int i = 0; i < returnSize; i++) 
	{
		printf("当前窗口%d的最大值为%d\n", i + 1, result[i]);
	}
	free(result);
	return 0;
}
Life's a struggle, I'll conquer it.
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇