当前位置: 首页 > news >正文

栈和队列OJ练习题及解答

前言

        上一篇博客已经讲到了栈和队列的数据结构,概括一下:栈后进先出(Last In First Out)、队列先进先出(First In First Out)。那么,接下来就来讲讲,关于栈和队列的相关练习题,进一步掌握栈和队列的使用。

一. 用队列实现栈

1. 题目描述

        请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(pushtoppop 和 empty)。

实现 MyStack 类:

  • void push(int x) 将元素 x 压入栈顶。
  • int pop() 移除并返回栈顶元素。
  • int top() 返回栈顶元素。
  • boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

注意:

  • 你只能使用队列的标准操作 —— 也就是 push to backpeek/pop from frontsize 和 is empty 这些操作。
  • 你所使用的语言也许不支持队列。 你可以使用 list (列表)或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

示例:

输入:
["MyStack", "push", "push", "top", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 2, 2, false]解释:
MyStack myStack = new MyStack();
myStack.push(1);
myStack.push(2);
myStack.top(); // 返回 2
myStack.pop(); // 返回 2
myStack.empty(); // 返回 False

提示:

  • 1 <= x <= 9
  • 最多调用100 次 pushpoptop 和 empty
  • 每次调用 pop 和 top 都保证栈不为空

进阶:你能否仅用一个队列来实现栈。

2. 解题思路

        根据上述题目描述,我们需要用两个队列来模拟栈后进先出(Last In First Out),那么问题就在于达到先进后出的效果,怎么如数据和出数据。

        首先队列出数据的话是从队头出,为了达到后出的效果,需要把其他的数据暂时存储起来,这个时候我们的第二个队列的作用就出现了,可以把在其他的数据转移到第二个队列,记录第一个队列头数据,最后清空第一个队列,达到这样的效果。如图1-1所示:

图1-1 双队列模拟栈读取删除数据

        输入的话就将所有数据录入到非空的队列,确保顺序性。

        关于进阶——用一个队列模拟栈:队列里入数据还是一样入,出数据的话就先把队列中前面的数据尾插到原队列,按照这个思路,我们需要知道需要尾插多少次,就在模拟栈的结构里增加一个记录数据总数的整形变量,每次删除数据都尾插数据总数减一次。如图1-2所示:

图1-2 单队列模拟栈出数据

3. 解题代码

        解题代码采用两个队列模拟栈的思路,有兴趣的小伙伴可以尝试单队列模拟。

3.1. 基础代码

        因为需要用队列模拟栈,而C语言不像C++那样能够直接使用库中的队列,所以这里直接提供给大家队列的代码。代码如下:


typedef int QDataType;
// 链式结构:表示队列 
typedef struct QListNode 
{ struct QListNode* _next; QDataType _data; 
}QNode; // 队列的结构 
typedef struct Queue 
{ QNode* _front; QNode* _rear; 
}Queue; // 初始化队列 
void QueueInit(Queue* q)
{assert(q);q->_front = q->_rear = NULL;
}// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
bool QueueEmpty(Queue* q)
{assert(q);return q->_front == NULL;
}// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{assert(q);if(QueueEmpty(q)){return 0;}else{QNode* cur = q->_front;int count = 0;while(cur){++count;cur = cur->_next;}return count;}
}// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{assert(q);QNode* newnode = (QNode*)malloc(sizeof(QNode));if(newnode == NULL){perror("QueuePush malloc fail");return;}newnode->_data = data;newnode->_next = NULL;if(q->_front == NULL){q->_front = q->_rear = newnode;}else{q->_rear->_next = newnode;q->_rear = q->_rear->_next;}
}// 队头出队列 
void QueuePop(Queue* q)
{assert(q);assert(!QueueEmpty(q));if(q->_front == q->_rear){free(q->_front);q->_front = q->_rear = NULL;}else{QNode* next = q->_front->_next;free(q->_front);q->_front = next;}
}// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->_front->_data;
}// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{assert(q);assert(!QueueEmpty(q));return q->_rear->_data;
}// 销毁队列 
void QueueDestroy(Queue* q)
{assert(q);//用cur遍历链表QNode* cur = q->_front;//遍历while(cur){//保存下一个位置节点QNode* next = cur->_next;free(cur);//释放内存//移动cur = next;}//队列中指针置为NULLq->_front = q->_rear = NULL;
}

3.2. 题目要求的函数实现

3.2.1. 栈的结构

        栈里面包含两个队列,如下所示:

typedef struct {Queue q1;Queue q2;
} MyStack;
3.2.2. 初始化栈

        为栈的结构开辟空间,并将队列初始化,代码如下:

MyStack* myStackCreate() {MyStack* st = (MyStack*)malloc(sizeof(MyStack));QueueInit(&(st->q1));QueueInit(&(st->q2));return st;
}
3.2.3. 销毁栈

        首先释放栈中队列所开辟的空间然后释放栈开辟的空间,代码如下:

void myStackFree(MyStack* obj) {QueueDestroy(&(obj->q1));QueueDestroy(&(obj->q2));free(obj);
}
3.2.4. 判断栈是否为空

        检查两个队列里是否存在数据,都没有栈就为空,这里直接调用队列为空的函数即可,代码如下:

bool myStackEmpty(MyStack* obj) {return QueueEmpty(&(obj->q1)) && QueueEmpty(&(obj->q2));
}
3.2.5. 入栈

        向非空的队列入数据,代码如下:

void myStackPush(MyStack* obj, int x) {assert(obj);//如果队列1不为空,则向队列1中录入数据if(!QueueEmpty(&(obj->q1))){QueuePush(&(obj->q1), x);}else//反之就录入数据到队列2{QueuePush(&(obj->q2), x);}
}
3.2.6. 出栈

        根据2.解题思路,代码如下:

int myStackPop(MyStack* obj) {assert(obj);//假设非空的队列为队列2Queue* emp = &(obj->q1);Queue* noemp = &(obj->q2);//如果队列2为空,就交换队列指针if(QueueEmpty(noemp)){emp = &(obj->q2);noemp = &(obj->q1);}//将非空队列前面的数据储存到另一个队列while(QueueSize(noemp) > 1){int x = QueueFront(noemp);QueuePop(noemp);QueuePush(emp, x);}//记录最后一个队列并输出int ret = QueueFront(noemp);QueuePop(noemp);return ret;
}
3.2.7. 访问栈顶数据

        向非空的队列访问最后储存的数据,代码如下:

int myStackTop(MyStack* obj) {assert(obj);//如果队列1为空就访问队列1末尾if(QueueEmpty(&(obj->q1))){return QueueBack(&(obj->q2));}else//反之访问队列2末尾{return QueueBack(&(obj->q1));}
}

3.3. 运行结果

        判题无误:

图1-3 队列模拟栈题解结果

二. 用栈实现队列

1. 题目描述

        请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

说明:

  • 你 只能 使用标准的栈操作 —— 也就是只有 push to toppeek/pop from topsize, 和 is empty 操作是合法的。
  • 你所使用的语言也许不支持栈。你可以使用 list 或者 deque(双端队列)来模拟一个栈,只要是标准的栈操作即可。

示例 1:

输入:
["MyQueue", "push", "push", "peek", "pop", "empty"]
[[], [1], [2], [], [], []]
输出:
[null, null, null, 1, 1, false]解释:
MyQueue myQueue = new MyQueue();
myQueue.push(1); // queue is: [1]
myQueue.push(2); // queue is: [1, 2] (leftmost is front of the queue)
myQueue.peek(); // return 1
myQueue.pop(); // return 1, queue is [2]
myQueue.empty(); // return false

提示:

  • 1 <= x <= 9
  • 最多调用 100 次 pushpoppeek 和 empty
  • 假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)

进阶:

  • 你能否实现每个操作均摊时间复杂度为 O(1) 的队列?换句话说,执行 n 个操作的总时间复杂度为 O(n) ,即使其中一个操作可能花费较长时间。

2. 解题思路

        用两个栈模拟队列的先进先出(First In First Out),因为栈只能从末尾读取数据,如果要像队列那样保持数据进入的顺序就需要找到队头数据,问题就相当于有两个杯子怎么喝到水杯底部的水。

        所以我们将栈分为入数据的栈和出数据的栈,需要入数据的时候就把出数据的栈的数据放到入数据的栈中然后入数据,反之亦然。如图2-1所示:

图2-1 栈模拟队列1

        这样每次进入数据都需要倒弄栈中的数据时间复杂度为O(N),那么如何降低时间复杂度呢?其实我们不难发现,没必要一直倒弄两个栈中的数据,如果出队列的时候出数据的栈没有数据在将数据倒入出栈栈即可。这样,入队列不需要把出栈的数据倒回去了。如图2-2所示:

图2-2 栈模拟队列2

3. 解题代码

        本题解法直接采用进阶解法。

3.1. 基础代码

        因为需要使用栈的结构,所以这里提供栈的相关代码:

#define INIT 4// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{STDataType* _a;int _top;		// 栈顶int _capacity;  // 容量 
}Stack;// 初始化栈 
void StackInit(Stack* ps); 
// 入栈 
void StackPush(Stack* ps, STDataType data); 
// 出栈 
void StackPop(Stack* ps); 
// 获取栈顶元素 
STDataType StackTop(Stack* ps); 
// 获取栈中有效元素个数 
int StackSize(Stack* ps); 
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps); 
// 销毁栈 
void StackDestroy(Stack* ps); // 初始化栈 
void StackInit(Stack* ps)
{assert(ps);STDataType* newnode = (STDataType*)malloc(sizeof(STDataType) * INIT);if(newnode == NULL){perror("StackInit malloc fail");exit(1);}ps->_a = newnode;ps->_top = 0;ps->_capacity = INIT;
}// 入栈 
void StackPush(Stack* ps, STDataType data)
{assert(ps);//容量不足扩容if(ps->_top == ps->_capacity){STDataType* newnode = (STDataType*)realloc(ps->_a, sizeof(STDataType) * ps->_capacity * 2);if(newnode == NULL){perror("StackInit malloc fail");exit(1);}ps->_a = newnode;ps->_capacity *= 2;}//入栈ps->_a[ps->_top] = data;++ps->_top;
}// 出栈 
void StackPop(Stack* ps)
{assert(ps);if(!StackEmpty(ps)){--ps->_top;}
}// 获取栈顶元素 
STDataType StackTop(Stack* ps)
{assert(ps);return ps->_a[ps->_top - 1];//栈顶元素在top的上一位
}// 获取栈中有效元素个数 
int StackSize(Stack* ps)
{return ps->_top;
}// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
bool StackEmpty(Stack* ps)
{assert(ps);return ps->_top == 0;
}// 销毁栈 
void StackDestroy(Stack* ps)
{assert(ps);free(ps->_a);ps->_a = NULL;ps->_capacity = ps->_top = 0;
}

3.2. 题目要求的函数实现

3.2.1. 队列结构
typedef struct {Stack st_push;Stack st_pop;
} MyQueue;

3.2.2. 队列初始化

MyQueue* myQueueCreate() {//开辟队列结构的空间MyQueue* qu = (MyQueue*)malloc(sizeof(MyQueue));if(qu == NULL){perror("malloc fail");return NULL;}//初始化两个栈StackInit(&(qu->st_pop));StackInit(&(qu->st_push));//返回队列空间指针return qu;
}
3.2.3. 销毁队列
void myQueueFree(MyQueue* obj) {//分别释放栈开辟的空间StackDestroy(&(obj->st_pop));StackDestroy(&(obj->st_push));//释放队列的空间free(obj);
}
3.2.4. 队列判空
bool myQueueEmpty(MyQueue* obj) {//两个栈都没数据,队列才为空return StackEmpty(&(obj->st_pop)) &&  StackEmpty(&(obj->st_push));
}
3.2.5. 队列入数据
void myQueuePush(MyQueue* obj, int x) {assert(obj);//记录入队列的栈指针,也可以不计,这里方便读者理解简化了Stack* _push = &(obj->st_push);//将数据录入入栈StackPush(_push, x);
}
3.2.6. 队列出数据
int myQueuePop(MyQueue* obj) {//记录入队列的栈指针,也可以不计,这里方便读者理解简化了Stack* _pop = &(obj->st_pop);Stack* _push = &(obj->st_push);//如果出数据的栈为空,就将入数据的栈中数据导入到出数据的栈if(StackEmpty(_pop)){while(!StackEmpty(_push)){int tmp = StackTop(_push);StackPop(_push);StackPush(_pop, tmp);}}//记录需要出队列的数据,删除并输出int ret = StackTop(_pop);StackPop(_pop);return ret;
}
3.2.7.  队列获取头数据

        直接从出数据的栈中获取栈顶元素,没有元素就将入数据栈中元素导入,代码如下:

int myQueuePeek(MyQueue* obj) {Stack* _pop = &(obj->st_pop);Stack* _push = &(obj->st_push);//如果出数据的栈为空,就将入数据的栈中数据导入到出数据的栈if(StackEmpty(_pop)){while(!StackEmpty(_push)){int tmp = StackTop(_push);StackPop(_push);StackPush(_pop, tmp);}}//输出出数据栈头数据int ret = StackTop(_pop);return ret;
}

3.3. 运行结果

        结果无误:

图2-3 栈模拟队列的结果

三. 设计循环队列

1. 题目描述

        设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

        循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。
  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。

示例:

MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为 3
circularQueue.enQueue(1);  // 返回 true
circularQueue.enQueue(2);  // 返回 true
circularQueue.enQueue(3);  // 返回 true
circularQueue.enQueue(4);  // 返回 false,队列已满
circularQueue.Rear();  // 返回 3
circularQueue.isFull();  // 返回 true
circularQueue.deQueue();  // 返回 true
circularQueue.enQueue(4);  // 返回 true
circularQueue.Rear();  // 返回 4

提示:

  • 所有的值都在 0 至 1000 的范围内;
  • 操作数将在 1 至 1000 的范围内;
  • 请不要使用内置的队列库。

2. 解题思路

2.1. 顺序表模拟

        如果用循序表模拟循环队列,则需要两个指针,指针一指向队列的头,一个指向数组的尾部。入数据从数组尾部进入,队列头用来删除数据,数组开辟的大小为顺序链表的容量。如果循环队列悟空用两个指针指向同一位置来表示,那么想要表示队列为满有两种方式:(1)在队列中增加一个变量记录数组中存在的数据个数。(2)开辟数组大小的时候多开一个空出的空间,那么数组为满的表示为尾指针加一等于头指针。

图3-1 顺序表模拟循环队列

2.2. 链表模拟

        如果用链表模拟就比较麻烦,需要先将链表的空间全部开好,那么剩下的各种操作与顺序表模拟循环队列相同。相比较起来,单向链表模拟如果需要读取队尾数据会比较麻烦,需要将尾指针遍历到尾指针之前的节点,所以使用双向链表模拟会更好,但是那从空间上来说不如顺序表模拟。如果找一个变量记录数据个数,插入的时候按照双向链表尾插,只是限制最后插入的节点个数未必不可行。

3. 解题代码

3.1. 题目要求的函数实现

        根据2.1.的解题思路。

3.1.1. 循环队列的结构
//定义存储数据的类型
typedef int QueueDataType;typedef struct {QueueDataType* a; //顺序表位置int pcur;  //头指针int ptail; //尾指针int size;  //限制的循环队列大小
} MyCircularQueue;
3.1.2. 循环队列初始化

        包括开辟空间,各项指针置为0,记录队列容量,代码如下:

MyCircularQueue* myCircularQueueCreate(int k) {MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));if(cq == NULL){perror("malloc fail");return NULL;}cq->a = (QueueDataType*)malloc(sizeof(QueueDataType) * (k + 1));cq->pcur = cq->ptail = 0;cq->size = k;return cq;
}
3.1.3. 判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {assert(obj);return obj->ptail == obj->pcur;
}
3.1.4. 判断队列中数据是否满了

        向这总增加的都需要用总容量取模,防止溢出。

bool myCircularQueueIsFull(MyCircularQueue* obj) {assert(obj);return (obj->ptail + 1) % (obj->size + 1) == obj->pcur;
}
3.1.5. 向队列中增加数据
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {assert(obj);//队列满员了就无法添加if(myCircularQueueIsFull(obj)){return false;}else{obj->a[obj->ptail++] = value;obj->ptail %= (obj->size + 1);return true;}
}
3.1.6. 从队列中删除数据
bool myCircularQueueDeQueue(MyCircularQueue* obj) {assert(obj);//如果队列为空则删除失败if(myCircularQueueIsEmpty(obj)){return false;}else{++obj->pcur;obj->pcur %= (obj->size + 1);return true;}
}
3.1.7. 从队头获取数据
int myCircularQueueFront(MyCircularQueue* obj) {assert(obj);//队列为空返回-1if(myCircularQueueIsEmpty(obj)){return -1;}else//反之返回数据{return obj->a[obj->pcur];}
}
3.1.8. 从队尾获取数据
int myCircularQueueRear(MyCircularQueue* obj) {assert(obj);//为空返回-1if(myCircularQueueIsEmpty(obj)){return -1;}else//队尾指针-1+k+1最后取模得到后一位的地址{return obj->a[(obj->ptail + obj->size) % (obj->size + 1)];}
}

3.2. 运行结果

        结果无误:

图3-2 

作者结语

        虽然说代码能够解开谜题,但是用文本的方式真的很难把题目短时间说清楚。具体细节还需要读者自己体会,这里最多算是抛了一个砖。

        感谢大家看到这里,那也说明写博客的时间没有白费。

相关文章:

栈和队列OJ练习题及解答

前言 上一篇博客已经讲到了栈和队列的数据结构&#xff0c;概括一下&#xff1a;栈后进先出&#xff08;Last In First Out&#xff09;、队列先进先出&#xff08;First In First Out&#xff09;。那么&#xff0c;接下来就来讲讲&#xff0c;关于栈和队列的相关练习题&#…...

渗透测试-信息收集

网络安全信息收集是网络安全领域中至关重要的一环&#xff0c;它涉及到对目标系统、网络或应用进行全面而细致的信息搜集和分析。这一过程不仅有助于理解目标网络的结构、配置和潜在的安全风险&#xff0c;还能为后续的渗透测试、风险评估和安全加固提供有力的支持。 在网络安…...

电力乙级资质延伸换证:企业转型的契机

电力乙级资质延伸换证不仅是企业合规运营的必要步骤&#xff0c;同时也为企业转型提供了重要的契机。在这个过程中&#xff0c;企业可以重新审视自身的业务模式、管理体系、技术能力等方面&#xff0c;寻找新的增长点和发展方向。 首先&#xff0c;电力乙级资质延伸换证要求企业…...

基于Redis实现分布式锁——Java版本

基于Redis实现分布式锁——Java版本 版本一版本二版本三Redisson 定义分布式锁接口如下&#xff1a; public interface ILock {boolean tryLock(long timeoutSec);void unlock(); }版本一 设定业务超时时间&#xff0c;到期自动解锁。缺点是超时时间不好估计&#xff0c;需要…...

Qt自定义控件--提升为

为什么要自定义控件 1&#xff0c;有复合小控件需要组合为一个整体控件时&#xff1b; 2&#xff0c;一个复合控件需要重复使用时&#xff1b; 实现 自定义控件文件 新增三个文件 关联不同组的控件 关联之前的准备工作 1&#xff0c;在主控件选择和子控件所有控件所在控件…...

Lua 基础 01 入门

Lua 基础相关知识 第一期 注释 -- 单行注释--[[多行注释 --]]-- 多加一个横杠符号就能重新启用注释内的代码 ---[[print("Lua") --]]数据类型 Lua 是动态类型语言&#xff0c;变量不需要类型定义&#xff0c;只需要为变量赋值。 Lua 有 8 种基本类型&#xff1a…...

远程连接阿里云ECS

说明&#xff1a;ECS&#xff08;阿里云服务器&#xff09;可选择的系统镜像如下&#xff1a; 本文介绍基于Windows系统&#xff0c;对CentOS、Ubuntu、Windows这三个操作系统的连接方式&#xff0c;以及连接工具Windterm的使用。 CentOS & Windterm CentOS是我使用时间最…...

【C++】多态(上)超详细

封装&#xff0c;继承&#xff0c;多态不只是C的三大特性&#xff0c;而是面向对象编程的三大特性。 什么是多态&#xff1a; 不同的对象做同一件事情&#xff0c;结果会出现多种形态。 1.满足多态的几个条件 1.父子类完成虚函数重写&#xff08;需要满足三同&#xff1a;函…...

【Git】 Git分支操作指南

隐形的纪念躲在心里面 也许吧 也许不会再见 阴天或晴天 一天又一年 风它在对我说莫忘这一切 &#x1f3b5; 蔡淳佳《隐形纪念》 Git是一种非常强大的分布式版本控制系统&#xff0c;允许用户在开发过程中创建不同的分支&#xff08;branch&#xff09;来分…...

智慧文旅赋能旅游服务升级:以科技创新驱动行业变革,打造智慧化、个性化、高效化的旅游新体验,满足游客日益增长的多元化需求

目录 一、引言 二、智慧文旅的概念与内涵 三、智慧文旅在旅游服务升级中的应用 1、智慧旅游服务平台建设 2、智慧景区管理 3、智慧旅游营销 四、智慧文旅推动旅游行业变革的案例分析 案例一&#xff1a;某智慧旅游城市建设项目 案例二&#xff1a;某景区智慧化改造项目…...

AtCoder Beginner Contest 310 E题 NAND repeatedly

E题&#xff1a;NAND repeatedly 标签&#xff1a;动态规划题意&#xff1a;给定一个长度为 n n n的 01 01 01字符串 A i A_i Ai​&#xff0c;给定规则&#xff1a; 0 ⊼ 0 1 , 0 ⊼ 1 1 , 1 ⊼ 0 1 , 1 ⊼ 1 0 0⊼01,0⊼11,1⊼01,1⊼10 0⊼01,0⊼11,1⊼01,1⊼10。 求 ∑…...

一款简易的免费抽奖软件

一、介绍 这款抽奖软件设计简洁&#xff0c;操作便捷。用户可以轻松将参与名单通过EXCEL文件导入至程序中&#xff0c;并可根据需要设定各类奖品和对应的中奖人数。在选定了奖品后&#xff0c;用户只需点击“开始”按钮&#xff0c;随后再按下“暂停”按钮&#xff0c;软件便会…...

Kubernetes 监控管理

目录 1. Metrics Server2. Prometheus & Grafana3. cAdvisor4. 日志收集5. 告警与通知6. 最佳实践 Kubernetes 监控管理是确保集群稳定运行和应用服务质量的关键环节。它涉及收集、聚合、分析集群及其上运行的应用程序的各种指标和日志数据。 1. Metrics Server 作用&…...

哈希表第6/9题--四数相加II

题目描述&#xff1a; 给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 示例 1&#xff1a; 输入&…...

使用JavaScript将富文本HTML转换为纯文本

在Web开发中&#xff0c;我们经常需要处理HTML内容&#xff0c;但有时为了特定的目的&#xff0c;比如文本处理、搜索或显示在非HTML环境中&#xff0c;我们可能希望将富文本HTML转换为纯文本。这里&#xff0c;我们将探讨如何使用JavaScript来实现这一功能。 为什么要将HTML转…...

2024-05-13 问AI: 介绍一下 google wavenet 声码器

文心一言 Google的WaveNet声码器是一个深度学习模型&#xff0c;用于生成高质量的音频信号&#xff0c;特别是人类语音。与传统的声码器相比&#xff0c;WaveNet可以生成更加自然和流畅的音频&#xff0c;因为它直接模拟了原始音频信号的波形生成过程。 WaveNet的核心思想是使…...

当代 Qt 正确的 安装方法 及 多版本切换

此文写于 20240511 首先去网站Index of /official_releases/online_installers下载一个安装器 安装器有什么用? 可以浏览安装版本 安装组件 安装器版本越能 能装的东西越多 现在只能选Qt5 和 Qt6 至于你公司用的Qt4 我也没招 见招时再拆招 安装器 默认国外源 可以换国内…...

matlab使用教程(70)—修改坐标区属性

1.控制坐标轴长度比率和数据单位长度 您可以控制 x 轴、y 轴和 z 轴的相对长度&#xff08;图框纵横比&#xff09;&#xff0c;也可以控制一个数据单位沿每个轴的相对长度&#xff08;数据纵横比&#xff09;。 1.1图框纵横比 图框纵横比是 x 轴、y 轴和 z 轴的相对长度。默认…...

手撕C语言题典——反转链表

目录 前言 一.思路 1&#xff09;创建新链表 2&#xff09;创建三个指针 二.代码实现 搭配食用更佳哦~~ 数据结构之单单单——链表-CSDN博客 数据结构之单链表的基本操作-CSDN博客 前面学了单链表的相关知识&#xff0c;我们来尝试做一下关于顺序表的经典算法题~ 前言 反转…...

用lobehub打造一个永久免费的AI个人助理

Lobe Chat是一个开源的高性能聊天机器人框架&#xff0c;它被设计来帮助用户轻松创建和部署自己的聊天机器人。这个框架支持多种智能功能&#xff0c;比如语音合成&#xff08;就是让机器人能说话&#xff09;&#xff0c;还能理解和处理多种类型的信息&#xff0c;不仅限于文字…...

Linux网络编程】传输层中的TCP和UDP(UDP篇)

【Linux网络编程】传输层中的TCP和UDP&#xff08;UDP篇&#xff09; 目录 【Linux网络编程】传输层中的TCP和UDP&#xff08;UDP篇&#xff09;传输层再谈端口端口号范围划分认识知名端口号netstatiostatpidofxargs UDP协议UDP协议端格式UDP的特点面向数据报UDP的缓冲数据UDP使…...

Ciphey无法安装的解决办法

安装过程纯属自己实践&#xff0c;满满干货 困扰我几天的问题终于解决了 我看着教程在window上安装 python3.8/python3.9/python3.10无论如何都安装不上&#xff0c; 在win10虚拟机仍然安装不上 可能是我电脑环境问题 解决办法&#xff1a; 在kali中安装&#xff0c;但是…...

交互之舞:Processing中的用户互动与响应设计

前言&#xff1a; &#x1f31f;在前两篇文章中&#xff0c;我们已经学会了如何绘制静态图形和创建动态动画。今天&#xff0c;我们将迈入一个新的领域——交互设计。在Processing中&#xff0c;用户互动是创造沉浸式体验的关键。让我们一起探索如何让用户与你的艺术作品互动&…...

unetr_plus_plus(UNETR++、nnU-Net)系列数据处理理解汇总

unetr_plus_plus&#xff08;UNETR、nnU-Net&#xff09;系列数据处理理解汇总&#xff0c;这是一个 3D 图像分割的任务系列集。 为什么说他们是一个系列集合呢&#xff1f;主要是因为&#xff1a; 论文的训练和评价数据集是一样的&#xff0c;都是来自于10全挑战赛&#xff…...

稻盛和夫《活法》读后感

最近几天又重读了一边稻盛和夫的《活法》&#xff0c;里面的观点让我感触颇多&#xff0c;现分享给诸君。 稻盛和夫毕业后&#xff0c;适逢经济萧条&#xff0c;没有好机会进入大公司深造&#xff0c;只能在一名教授的推荐下进入了一家做陶瓷绝缘体的公司&#xff0c;虽然公司…...

Smurf 攻击是不是真的那么难以防护

Smurf攻击是一种网络攻击方式&#xff0c;属于分布式拒绝服务&#xff08;DDoS&#xff09;攻击的变种。以 1990 年代流行的名为 Smurf 的漏洞利用工具命名。该工具创建的 ICMP 数据包很小&#xff0c;但可以击落大目标。 它利用ICMP协议中的回声请求&#xff08;ping&#x…...

ASP.NET之图像控件

在ASP.NET中&#xff0c;用于显示图像的控件主要是Image控件&#xff0c;Image控件属于ASP.NET Web Forms的一部分&#xff0c;它允许你在Web页面上显示图像。以下是如何在ASP.NET Web Forms中使用 1. 添加Image控件到页面 在ASP.NET Web Forms页面上&#xff0c;你可以通过设…...

二级Java第五套真题(乱序版)含真题解析

一. 单选题(共39题,39分) 1. (单选题, 1分) 阅读下列代码 public class Test implements Runnable { public void run (Thread t) { System.out.println("Running."); } public static void main (String[ ] args) { T…...

【C++】GNU Debugger (GDB) 使用示例

文章目录 GDB 使用示例GDB的常用命令示例 GDB 使用示例 GDB的常用命令 GDB&#xff08;GNU Debugger&#xff09;是一种Unix下的程序调试工具&#xff0c;用于调试C、C等编程语言编写的程序。以下是一些GDB的常用命令&#xff1a; 启动和退出&#xff1a; run 或 r&#xf…...

Qlik Sense :使用智能搜索Smart Search

智能搜索 智能搜索是 Qlik Sense 中的全局搜索工具&#xff0c;可让您从应用程序中的任何工作表搜索应用程序中的整个数据集。可通过点击 从工作表中的选择项栏使用智能搜索。 通过智能搜索字段&#xff0c;您可以从任何工作表搜索您的应用程序中的完整数据集。 信息注释 智…...