zoukankan      html  css  js  c++  java
  • Leetcode 430. 扁平化多级双向链表

    1。利用了栈stack后进先出的性质,存储带 孩子结点 的 结点 的下一个结点.


    class
    Solution{ public: Node* flatten(Node* head) { if(!head) return NULL; Node* p=new Node(); p=head; Node* prehead=p; stack<Node*>ss; while(true) { if(p->child!=NULL) { //当前结点有孩子结点,则记录下来当前结点的下一个结点,用于之后返回来对接 Node* rem=new Node(); rem=p->next; //判断当前结点的下一个结点是不是空的,如果是空的,则说明这个结点是这一层的最后一个,返回的时候直接返回上上一层 if(rem) ss.push(rem); p->next=p->child; p->child->prev=p; //将孩子结点连入结果链表中之后,要把当前结点的孩子结点置位NULL p->child=NULL; p=p->next; } else { //当前结点没有孩子结点, //这一层遍历完了,需要返回上一层啦,利用了stack后进先出的性质,从里往外一层一层的剥开 if(p->next==NULL&&ss.size()>0) { Node *temp=ss.top(); ss.pop(); p->next=temp; temp->prev=p; p=p->next; } //返回到最外面这一层了,且到达最外层的最后一个了,可以跳出结束了。 else if((p->next==NULL&&ss.size()==0)) break; //处在某层的某个中间位置,挨个遍历吧 else p=p->next; } } return prehead; } };

    2.

    stack
    常规DFS遍历,使用stack(LIFO)遍历整个链表
    取出每个节点,压入栈内,再按顺序(LIFO)一个个取出,加上两个节点间的关系
    记得清空child指针
    注意while循环内前两个if语句的顺序,先next的节点,后child节点。(LIFO)

    class Solution{
    public:
        Node* flatten(Node* head){
        if(!head) return NULL;
        Node* curr;
        stack<Node*>stk;
        stk.push(head);
        Node *pre=NULL;
        while(!stk.empty())
        {
            curr=stk.top();
            stk.pop();
            if(curr->next!=NULL)
                stk.push(curr->next);
            if(curr->child!=NULL)
            {
              stk.push(curr->child);
              curr->child=NULL;
            }
                
            if(pre)
            {
                pre->next=curr;
                curr->prev=pre;
            }
            pre=curr;
        }
        return head;
      }
    };

    3.递归

    递归法

     若child为nllptr,将指针移向next节点
     若child不为空,进入递归,传入头节点(即,child的第一位)
     连接子链表的尾端和父节点的下一节点。
     用nextnode记录有child的节点的下一个节点,用来连接在子链表的尾端
     通过判断到达链表尾端时,nextnode是否为nullptr,若是,则该尾端就是第一级链表的尾端,若不是,该尾端就是子链表的尾端。(注意使用nextnode连接子链表后,需要将nextnode清空,否则会重复连接子链表)
     prevnode用来记录temp的前一个节点,当temp到尾端时为null,这时用prevnode来连接nextnode。

    class Solution {
    public:
        Node* flatten(Node* head) {
            Node *temp = head;
            Node *nextnode = nullptr;
            Node *prevnode = head;
            while(prevnode){
                if(temp && temp -> child){
                    nextnode = temp -> next; //记录当前节点的下一个节点
                    temp -> child -> prev = temp;
                    temp -> next = flatten(temp -> child); //进入递归
                    temp -> child = nullptr; //注销当前节点的child;
                }
                prevnode = temp; //记录null节点的前一个节点
                if(temp)    temp = temp -> next;
                if(nextnode && !temp){ //当同一级链表存在下一个节点(即,原来有child的节点的下一节点),且子链表到达null
                    prevnode -> next = nextnode; //连接子节点和之前记录的nextnode所指链表 ---->这一步将其中两级双向链表扁平化
                    nextnode -> prev = prevnode;
                    temp = prevnode -> next;
                    nextnode = nullptr; //记得清空使用过的nextnode,否则会将无限连接nextnode所指链表
                }
            }
            return head;
        }
  • 相关阅读:
    Android架构详解
    wince下实现GPRS上网,程序控制拨号 .
    wince串口蓝牙
    添加蓝牙通讯功能
    c# 注册表.代码示例.(迭代遍历注册表)[Demo]
    Vim Tips
    北京大学与苏州大学学生社会来源研究(1952年2002年) (zz)
    ES6的循环和可迭代对象
    JavaScript之this
    js数组去重的方法
  • 原文地址:https://www.cnblogs.com/renzmin/p/11883949.html
Copyright © 2011-2022 走看看