zoukankan      html  css  js  c++  java
  • DS博客作业02--栈和队列

    0.PTA得分截图

    1.本周学习总结

    1.1 总结栈和队列内容

    1.栈的存储结构及操作

    1.栈

    1.栈(stack):是限定仅在表尾进行插入和删除操作的线性表。其中,允许插入和删除的一端被称为栈顶(top),另一端被称为栈底(bottom),不含任何数据元素的栈被称为空栈。栈又被称为后进先出(Last In First Out)的线性表,简称LIFO结构。
    栈的插入操作为进栈,栈的删除操作为出栈。

    2.栈的抽象数据类型
    ADT 栈(stack)
    Data
    同线性表。元素具有相同类型,相邻元素具有前驱和后继关系。
    Operation
    InitStack(S):初始化操作,建立一个空栈S。
    DestoryStack(
    S):若栈存在,则销毁它。
    ClearStack(S):将栈清空。
    StackEmpty(S):若栈为空,返回true,否则返回false。
    GetTop(S,
    e):若栈存在且非空,用e返回S的栈顶元素。
    Push(S,e):若栈S存在,插入新元素e到栈S中并称为栈顶元素
    Pop(
    S,*e):删除栈S中栈顶元素,并用e返回其值
    StackLength(S):返回栈S的元素个数
    endADT

    2.栈的存储结构

    (1)栈顺序结构定义

    #define OK 1
    #define ERROR 0
    typedef int SElemType;    //SElemType类型根据实际情况而定,这里假设为int
    typedef struct
    {
        SElemType data[MAXSIZE];    //栈存储空间大小MAXSIZE
        int top;    //用于栈顶指针
    }SqStack;
    

    (2)共享栈

    3.栈的顺序存储结构
    栈类型SqStack:

    typedef struct 
    {  ElemType data[MaxSize]; 
       int top;		//栈顶指针
    } Stack;
    typedef Stack *SqStack;
    



    顺序栈4要素:
    栈空条件:top=-1
    栈满条件:top=MaxSize-1
    进栈e操作:top++; st->data[top]=e
    退栈操作:e=st->data[top]; top--;
    顺序栈中实现栈的基本运算算法
    (1)初始化栈initStack(&s)

    void InitStack(SqStack &s)
    {  s=new Stack;     
        s->top=-1;
      }
    

    (2)销毁栈ClearStack(&s)

    void DestroyStack(SqStack &s)
    {
      delete s;
    }
    

    (3)判断栈是否为空StackEmpty(s)

    bool StackEmpty(SqStack s)
    {
      return(s->top==-1);
    }
    

    (4)进栈操作(从栈顶插入一个元素)
    算法思路:
    a.判定是否栈满;
    b.栈顶加1;
    c.将元素插入到
    实现:插入元素e为新的栈顶元素

    Status Push(SqStack *S,SElemType e)
    {
        if(S->top==MAXSIZE-1)    //栈顶=MAXSIZE-1,即数组的最后一个存储位置,说明栈满
        {
            return ERROR;
        }
        S->top++;    //栈顶加1
        S->data[S->top]=e;    //将元素入栈
        return OK;
    }
    

    (5)出栈操作(从栈顶删除一个元素)
    算法思路:
    a.判定栈是否为空;
    b.将栈顶元素保存到指针变量e所指向的存储位置中;
    c.栈顶减1.
    实现:若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

    Status Pop(SqStack *S,SElemType *e)
    {
        if(S->top==-1)    //空栈
        {
            return ERROR;
        }
        *e=S->data[S->top];
        S->top--;
        return OK;
    }
    

    (6)取栈顶元素GetTop(s)
    在栈不为空的条件下,将栈顶元素赋给e。

    bool GetTop(SqStack *s,ElemType &e)
    {	
       if (s->top==-1)	//栈为空的情况    
        return false;
        e=s->data[s->top];	    
        return true;
    }
    

    2.栈的应用

    ------------恢复内容开始------------

    0.PTA得分截图

    1.本周学习总结

    1.1 总结栈和队列内容

    1.栈的存储结构及操作

    1.栈

    1.栈(stack):是限定仅在表尾进行插入和删除操作的线性表。其中,允许插入和删除的一端被称为栈顶(top),另一端被称为栈底(bottom),不含任何数据元素的栈被称为空栈。栈又被称为后进先出(Last In First Out)的线性表,简称LIFO结构。
    栈的插入操作为进栈,栈的删除操作为出栈。

    2.栈的抽象数据类型
    ADT 栈(stack)
    Data
    同线性表。元素具有相同类型,相邻元素具有前驱和后继关系。
    Operation
    InitStack(S):初始化操作,建立一个空栈S。
    DestoryStack(
    S):若栈存在,则销毁它。
    ClearStack(S):将栈清空。
    StackEmpty(S):若栈为空,返回true,否则返回false。
    GetTop(S,
    e):若栈存在且非空,用e返回S的栈顶元素。
    Push(S,e):若栈S存在,插入新元素e到栈S中并称为栈顶元素
    Pop(
    S,*e):删除栈S中栈顶元素,并用e返回其值
    StackLength(S):返回栈S的元素个数
    endADT

    2.栈的存储结构

    1.栈的顺序存储结构
    栈类型SqStack:

    typedef struct 
    {  ElemType data[MaxSize]; 
       int top;		//栈顶指针
    } Stack;
    typedef Stack *SqStack;
    



    顺序栈4要素:
    栈空条件:top=-1
    栈满条件:top=MaxSize-1
    进栈e操作:top++; st->data[top]=e
    退栈操作:e=st->data[top]; top--;
    顺序栈中实现栈的基本运算算法
    (1)初始化栈initStack(&s)

    void InitStack(SqStack &s)
    {  s=new Stack;     
        s->top=-1;
      }
    

    (2)销毁栈ClearStack(&s)

    void DestroyStack(SqStack &s)
    {
      delete s;
    }
    

    (3)判断栈是否为空StackEmpty(s)

    bool StackEmpty(SqStack s)
    {
      return(s->top==-1);
    }
    

    (4)进栈操作(从栈顶插入一个元素)
    算法思路:
    a.判定是否栈满;
    b.栈顶加1;
    c.将元素插入到
    实现:插入元素e为新的栈顶元素

    Status Push(SqStack *S,SElemType e)
    {
        if(S->top==MAXSIZE-1)    //栈顶=MAXSIZE-1,即数组的最后一个存储位置,说明栈满
        {
            return ERROR;
        }
        S->top++;    //栈顶加1
        S->data[S->top]=e;    //将元素入栈
        return OK;
    }
    

    (5)出栈操作(从栈顶删除一个元素)
    算法思路:
    a.判定栈是否为空;
    b.将栈顶元素保存到指针变量e所指向的存储位置中;
    c.栈顶减1.
    实现:若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR

    Status Pop(SqStack *S,SElemType *e)
    {
        if(S->top==-1)    //空栈
        {
            return ERROR;
        }
        *e=S->data[S->top];
        S->top--;
        return OK;
    }
    

    (6)取栈顶元素GetTop(s)
    在栈不为空的条件下,将栈顶元素赋给e。

    bool GetTop(SqStack *s,ElemType &e)
    {	
       if (s->top==-1)	//栈为空的情况    
        return false;
        e=s->data[s->top];	    
        return true;
    }
    

    2.栈链式存储结构
    定义:

    typedef int ElemType;
    typedef struct linknode
    {  ElemType data;			//数据域
       struct linknode *next;	//指针域
    } LiNode,*LiStack;
    

    链栈中实现栈的基本运算算法:
    (1)初始化栈initStack(&s)

    void InitStack(LiStack &s)
    {  s=new LiNode;
       s->next=NULL;
    }
    


    (2)销毁栈ClearStack(&s)
    释放栈s占用的全部存储空间。同链表删除:

    void DestroyStack(LiStack &s)
    { LiStack p;
       while (s!=NULL)
       {	  p=s; 	
           s=s->next;
           free(p); 
       }
     }
    

    3)判断栈是否为空StackEmpty(s)
    栈S为空的条件是s->next==NULL,同空链表

    bool StackEmpty(LiStack s)
    {
       return(s->next==NULL);
    }
    

    (4)进栈Push(&s,e)
    将新数据节点插入到头节点之后。对应算法如下:

    void Push(LiStack &s,ElemType e)
    {  LiStack p;
       p=new LiNode;
       p->data=e;		//新建元素e对应的节点*p
       p->next=s->next;	//插入*p节点作为开始节点
       s->next=p;
    }
    

    (5)出栈Pop(&s,&e)
    在栈不为空的条件下,将头节点后继数据节点的数据域赋给e

    bool Pop(LiStack &s,ElemType &e)
    {  LiStack p;
       if (s->next==NULL)		//栈空的情况
    	return false;
       p=s->next;			//p指向开始节点
       e=p->data;
       s->next=p->next;		//删除*p节点
       free(p);				//释放*p节点
       return true;
    }
    

    6)取栈顶元素GetTop(s,e)
    在栈不为空的条件下,将头节点后继数据节点的数据域赋给e。

    bool GetTop(LiStack s,ElemType &e)
    {  if (s->next==NULL)	//栈空的情况
    	return false;
       e=s->next->data;
       return true;
    }
    

    stack容器:

    #include<stack>
    1.stack<int>  s:初始化栈,参数表示元素类型
    2.s.push(t):入栈元素t
    3.s.top():返回栈顶元素
    4.s.pop():出栈操作只是删除栈顶元素,并不返回该元素。
    5.s1.empty(),当栈空时,返回true。
    6.s1.size():访问栈中的元素个数
    

    2.栈的应用

    表达式求值
    中缀转后缀表达式
    中缀表达式:运算符号位于两个运算数之间。如 ,a + b *c - d / e
    后缀表达式:运算符号位于两个运算数之后。如, a b c *+ d e /- 
    exp:字符数组
    a + b * c - d / e * f
    postexp:后缀表达式数组
    a b c d e f
    1.优先级比栈顶运算符高入栈
    2.低或相等,出栈,写入后缀表达式
    例如:对于表达式“(56-20)/(4+2)”,其转换成后缀表达式的过程 如下:



    表达式“(56-20)/(4+2)”
    后缀表达式:
    56#20#-4#2#+/
    对后缀表达式postexp求值

    while (从postexp读取字符ch,ch!='')
    {    若ch为数字,将后续所有数字构成一个整数存放数值栈st中。
         若ch为“+”,则从数值栈st中退栈两个运数,相加后进栈st中。
         若ch为“-”,则从数值栈st中退栈两个数,相减后进栈st中。
         若ch为“*”,则从数值栈st中退栈两个数,相乘后进栈st中。
         若ch为“/”,则从数值栈st中退栈两个数,相除后进栈st中
            (若除数为零,则提示相应的错误信息)。}
    若字符串postexp扫描完毕,则数值栈op中的栈顶元素就是表达式的值。
    

    2.队列

    1.定义及特点

    定义:只允许在表的一端进行插入,而在表的另一端进行删除的线性表。
    队尾(rear)——允许插入的一端
    队头(front)——允许删除的一端
    特点:先进先出(FIFO)

    2.队列的顺序存储结构及其基本运算

    顺序队类型SqQueue定义如下:
    typedef struct 
    {     ElemType data[MaxSize]; 
          int front,rear;      //队首和队尾指针
    }   Queue;
    typedef Queue *SqQueue;
    

    队列的基本运算如下:

        InitQueue(&q):初始化队列。构造一个空队列q。
        DestroyQueue(&q):销毁队列。释放队列q占用的存储空间。
        QueueEmpty(q):判断队列是否为空。若队列q为空,则返回真;否则返回假。
        enQueue(&q,e):进队列。将元素e进队作为队尾元素。
        deQueue(&q,&e):出队列。从队列q中出队一个元素,并将其值赋给e。
    


    顺序队的四要素(初始时front=rear=-1):
    队空条件:front = rear
    队满条件:rear=MaxSize-1
    元素e进队:rear++;data[rear]=e;
    元素e出队:front++;e=data[front];

    1. 顺序队中实现队列的基本运算
      (1)初始化队列InitQueue(q)
        构造一个空队列q。将front和rear指针均设置成初始状态即-1值。
    void InitQueue(SqQueue &q)
    {	q=new Queue;
    	q->front=q->rear=-1;
    }
    

    (2)销毁队列DestroyQueue(q)
    释放队列q占用的存储空间。

    void DestroyQueue(SqQueue &q)
    {
      delete q;
    }
    

    3)判断队列是否为空QueueEmpty(q)
    若队列q满足q->front==q->rear条件,则返回true;否则返回false。

    bool QueueEmpty(SqQueue q)
    {
       return(q->front==q->rear);
    }
    

    (4)进队列enQueue(q,e)
    在队列不满的条件下,先将队尾指针rear循环增1,然后将元素添加到该位置。

    bool enQueue(SqQueue &q,ElemType e)
    {  
        if (q->rear+1==MaxSize)	   return false;
                                           //队满上溢出
    	q->rear=q->rear+1;
    	q->data[q->rear]=e;
    	return true;
    }
    

    5)出队列deQueue(q,e)
    在队列q不为空的条件下,将队首指针front循环增1,并将该位置的元素值赋给e。

    bool deQueue(SqQueue &q,ElemType &e)
    {	
             if (q->front==q->rear)  //队空下溢出
    		return false;
    	q->front=q->front+1;
    	e=q->data[q->front];
    	return true;
    }
    

    2、环形队列(或循环队列)中实现队列的基本运算
    把数组的前端和后端连接起来,形成一个环形的顺序表,即把存储队列元素的表从逻辑上看成一个环,称为环形队列或循环队列。

    队空:frontrear
    队满:front
    rear
    front指向队头元素问题,解决方案:
    (1).另外设一个标志以区别队空、队满
    (2).少用一个元素空间,front指队头前一个位置
    队空:frontrear
    队满:(rear+1)%M
    front
    (3).顺序队列没这个问题。
    初始化队列:front=rear=0
    队满条件:(rear+1)%MaxSize=front
    队空条件:front=rear
    入队操作:rear=(rear+1)%MaxSize
    data[rear]=e;
    出队操作:front=(front+1)%MaxSize
    data[front]=e;
    基本运算:
    (1)初始化队列InitQueue(q)
    构造一个空队列q。将front和rear指针均设置成初始状态即0值。

    void InitQueue(SqQueue &q)
    {   q=new Queue;
        q->front=q->rear=0;
    }
    

    (2) 销毁队列

    void DestroyQueue(SqQueue &q)
    {
    	delete q;
    }
    

    (3) 判断队列是否为空

    bool QueueEmpty(SqQueue q)
    {
    	return(q->front==q->rear);
    }
    

    (4) 进环形队列

    bool enQueue(SqQueue &q,ElemType e)
    {	if ((q->rear+1)%MaxSize==q->front)	//队满上溢出
    		return false;
    	q->rear=(q->rear+1)%MaxSize;
    	q->data[q->rear]=e;
    	return true;
    }
    

    (5) 出环形队列

    bool deQueue(SqQueue &q,ElemType &e)
    {	if (q->front==q->rear)		//队空下溢出
    		return false;
    	q->front=(q->front+1)%MaxSize;
    	e=q->data[q->front];
    	return true;
    }
    

    (6) 求循环队列的长度

    int  QueueLength (SqQueue Q)
    {   
         return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;                        
     }
    

    queue容器

    #include<queue>
    q1.push(x): 将x接到队列的末端。
    q1.pop():弹出队列的第一个元素
    注意,并不会返回被弹出元素的值。
    q1.front():即最早被压入队列的元素。
    q1.back():即最后被压入队列的元素。
    q1.empty():当队列空时,返回true。
    q1.size():访问队列中的元素个数
    

    3.链队列

    typedef struct QNode{
       QElemType   data;
       struct Qnode  *next;
    }Qnode, *QueuePtr;
    typedef struct {
       QueuePtr  front;            //队头指针   
       QueuePtr  rear;             //队尾指针
    }LinkQueue;  
    

    队空条件:front=rear
    队满条件:不考虑
    进队e操作:将包含e的节点插入到单链表表尾
    出队操作:删除单链表首数据节点
    空队列:

    元素x入队列:

    元素y入队列:

    元素x出队列:

    基本运算:
    (1) 链队列初始化

    Status InitQueue (LinkQueue &Q){
       Q.front=Q.rear=new QNode; 
        if(!Q.front) exit(OVERFLOW);
        Q.front->next=NULL;
         return OK;
    }
    

    (2) 销毁链队列

    Status DestroyQueue (LinkQueue &Q){
       while(Q.front){
          Q.rear=Q.front->next;
          free(Q.front);
          Q.front=Q.rear;   }    
       return OK;
    }
    

    (3) 判断链队列是否为空

    Status QueueEmpty (LinkQueue Q){
        return (Q.front==Q.rear);                             
     }
    

    (4) 求链队列的队头元素

    Status GetHead (LinkQueue Q, QElemType &e){
       if(Q.front==Q.rear) return ERROR;
       e=Q.front->next->data;
       return OK;
    }
    

    (5) 链队列入队

    Status EnQueue(LinkQueue &Q,QElemType e){
        p=(QueuePtr)malloc(sizeof(QNode));
        if(!p) exit(OVERFLOW);
        p->data=e; p->next=NULL;
        Q.rear->next=p;
        Q.rear=p;
        return OK;
    }
    


    (6) 链队列出队

    Status DeQueue (LinkQueue &Q,QElemType &e){
       if(Q.front==Q.rear) return ERROR;
       p=Q.front->next;
       e=p->data;
       Q.front->next=p->next;
       if(Q.rear==p) Q.rear=Q.front;
       delete p;
       return OK;
    }
    


    4.双端队列
    (1)两端都可以进队和出队操作的队列。
    (2)队列的两端分别称为前端和后端,两端都可以入队和出队。
    (3)其元素的逻辑结构仍是线性结构。

    3.队列应用

    操作系统、售票系统、打印机、手机短信发送
    例子:迷宫问题
    记录走过的方块:

    typedef struct 
    {      int i,j;		//方块的位置
           int pre		//本路径中上一方块在队列中的下标
    }  Box;			//方块类型
    typedef struct
    {     Box data[MaxSize];
           int front,rear;	//队头指针和队尾指针
    }  QuType;		//定义顺序队类型
    

    求一条迷宫路径的算法:

    bool mgpath1(int xi,int yi,int xe,int ye)	//搜索路径为:(xi,yi)->(xe,ye)
    {      Box e;
           int i, j, di, i1, j1;
           QuType *qu;		//定义顺序队指针qu
           InitQueue(qu);		//初始化队列qu
           e.i=xi;  e.j=yi;   e.pre=-1;
           enQueue(qu,e);		//(xi,yi)进队
           mg[xi][yi]=-1;		//将其赋值-1,以避免回过来重复搜索
     while (!QueueEmpty(qu))		//队不空循环
           {	deQueue(qu,e);			//出队方块e
    	i=e.i;   j=e.j;
    	if (i==xe && j==ye)		//找到了出口,输出路径
    	{       print(qu,qu->front);	//调用print函数输出路径
    	        DestroyQueue(qu);		//销毁队列
    	        return true;			//找到一条路径时返回真
    	}
     for (di=0;di<4;di++)		//循环扫描每个方位
            {	switch(di)
    	{
    	case 0:i1=i-1; j1=j;   break;
    	case 1:i1=i;   j1=j+1; break;
    	case 2:i1=i+1; j1=j;   break;
    	case 3:i1=i;   j1=j-1; break;
    	}
    	if (mg[i1][j1]==0)
    	{     e.i=i1;  e.j=j1; 
    	      e.pre=qu->front;	
    	      enQueue(qu,e);	//(i1,j1)方块进队
    	      mg[i1][j1]=-1;	//将其赋值-1
    	}
             }
          }
          DestroyQueue(qu);		//销毁队列
          return false;
    }
    

    队列:解决广度优先搜索算法。
    迷宫路径:最优解

    1.2.谈谈你对栈和队列的认识及学习体会。

    栈和队列各有各的优点,各有各的缺点,在做栈和队列问题时,画图是必不可少的,画图能帮助我们理清做题的思路,方便求解题目。
    栈和队列感觉还有点不懂,应该再反复认真学习!

    2.PTA实验作业

    2.1 jmu-报数游戏

    2.1.1 代码截图


    2.1.2 本题PTA提交列表说明。


    部分正确:题目没看清,少了“!”。
    部分正确:中间多打了一个空格。

    2.2 jmu-ds-舞伴问题

    2.2.1 代码截图


    2.2.2 本题PTA提交列表说明。


    格式错误:少了一个空格。

    3.阅读代码

    3.1 用两个栈实现队列

    题目:
    用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
    解题代码:

    class CQueue {
        Stack<Integer> stack1;
        Stack<Integer> stack2;
        int size;
    
        public CQueue() {
            stack1 = new Stack<Integer>();
            stack2 = new Stack<Integer>();
            size = 0;
        }
        
        public void appendTail(int value) {
            while (!stack1.isEmpty()) {
                stack2.push(stack1.pop());
            }
            stack1.push(value);
            while (!stack2.isEmpty()) {
                stack1.push(stack2.pop());
            }
            size++;
        }
        
        public int deleteHead() {
            if (size == 0) {
                return -1;
            }
            size--;
            return stack1.pop();
        }
    }
    

    3.1.1 该题的设计思路


    插入元素
    插入元素对应方法 appendTail
    如果 stack1 非空,则将 stack1 内的元素依次弹出并依次压入 stack2,直至 stack1 内的全部元素都被弹出
    将新元素 value 压入 stack1 内
    如果 stack2 非空,则将 stack2 内的元素依次弹出并依次压入 stack1,直至 stack2 内的全部元素都被弹出
    将 size 的值加 1
    时间复杂度:O(n)。
    空间复杂度:O(n)。

    删除元素
    删除元素对应方法 deleteHead
    如果 size 为 0,则队列为空,返回 -1
    如果 size 大于 0,则队列非空,将 size 的值减 1,从 stack1 弹出一个元素并返回
    时间复杂度:O(1)。
    空间复杂度:O(1)。

    3.1.2 该题的伪代码

    class CQueue {
    	Stack<Integer> stack1;//第一个栈
    	Stack<Integer> stack2;//辅助栈
    	int size;//队列元素数
    
    	public CQueue() {
    		初始化 stack1
    		初始化stack2
    		size = 0;//队列元素数开始为0
    	}
    
    	public void appendTail(int value) {
    		while (stack1不为空)
    			将stack1中新插入的元素push进stack2中
    		end while
    		新元素value入栈stack1
    		while (stack2非空)
    			将stack2中的元素再全部返回stack1中
    		end while
    		size++;
    	}
    
    	public int deleteHead() {
    		if 队列为空 
    			return -1;
    		end if
    		队列元素-1
    		return stack1.pop();
    	}
    }
    

    3.1.3 运行结果

    3.1.4分析该题目解题优势及难点。
    优势:
    一个栈存储元素,一个栈辅助操作。新插入的元素在第一个栈的底部,第一个栈内的其余元素的顺序和插入元素之前保持一致。大大节省了时间复杂度。
    难点:
    进行辅助操作和存储操作的两个栈的元素间的调换。

    3.2 根据身高重建队列

    题目:
    假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。

    注意:
    总人数少于1100人。
    解题代码:

    class Solution {
    public:
        vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
            // 先排序
            // [7,0], [7,1], [6,1], [5,0], [5,2], [4,4]
            
            // 再一个一个插入。
            // [7,0]
            // [7,0], [7,1]
            // [7,0], [6,1], [7,1]
            // [5,0], [7,0], [6,1], [7,1]
            // [5,0], [7,0], [5,2], [6,1], [7,1]
            // [5,0], [7,0], [5,2], [6,1], [4,4], [7,1]
            sort(people.begin(), people.end(), [](const vector<int>& a, const vector<int>& b) {
                if (a[0] > b[0]) return true;
                if (a[0] == b[0] && a[1] < b[1]) return true;
                return false;
            });
            
            vector<vector<int>> res;
            for (auto& e : people) {
                res.insert(res.begin() + e[1], e);
            }
            return res;
        }
    };
    

    3.2.1 该题的设计思路

    假设候选队列为 A,已经站好队的队列为 B.
    从 A 里挑身高最高的人 x 出来,插入到 B. 因为 B 中每个人的身高都比 x 要高,因此 x 插入的位置,就是看 x 前面应该有多少人就行了。比如 x 前面有 5 个人,那 x 就插入到队列 B 的第 5 个位置。

    时间复杂度:O(n)
    空间复杂度: O(1)

    3.2.2 该题的伪代码

    class Solution {
    public:
        vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), [](const vector<int>& a, const vector<int>& b) {
        先排序,按身高从高到矮;
        }
        vector<vector<int>> res;
            for (auto& e : people) {
               插入;
            }
    }
    

    3.2.3 运行结果

    3.2.4分析该题目解题优势及难点。

    难点:
    涉及多个c++容器,需要深入去了解这些容器的用法。
    优势:
    容易理清思路,不容易混淆。

  • 相关阅读:
    hdu 5366 简单递推
    hdu 5365 判断正方形
    hdu 3635 并查集
    hdu 4497 数论
    hdu5419 Victor and Toys
    hdu5426 Rikka with Game
    poj2074 Line of Sight
    hdu5425 Rikka with Tree II
    hdu5424 Rikka with Graph II
    poj1009 Edge Detection
  • 原文地址:https://www.cnblogs.com/201218zx/p/12548803.html
Copyright © 2011-2022 走看看