LeetCode-430. 扁平化多级双向链表-题解

题目链接

430. 扁平化多级双向链表 - 力扣(LeetCode)

题目介绍

你将得到一个双链表,节点包含一个"下一个"指针、一个"前一个"指针和一个额外的"子指针"。这个子指针可能指向一个单独的双向链表,并且这些链表也包含类似的特殊节点。子列表可以有一个或多个自己的子列表,从而形成多层数据结构。

给定链表的头节点head,需要将链表扁平化,使所有节点都出现在单层双链表中。对于带有子列表的节点curr,子列表中的节点应该位于扁平化列表中curr之后,以及curr.next之前。

返回扁平化后的列表头head,列表中的节点的所有子指针必须设置为null

题目知识点

涉及到高级数据双向链表(主要考察点 - 修改指针指向模拟符合题目要求)

/*

// Definition for a Node.

class Node {

public:

int val;

Node* prev;

Node* next;

Node* child;

};

*/

题目示例

题目分析

我们通过题目可以清晰地了解到该题目的目的很简单,只是通过模拟来完成扁平化处理,那么对于题目而言是什么是扁平化呢,只有当包含有子指针时才会有扁平化操作,因此只是一个遍历当前节点并找到没有子指针结束的节点,不断的递归。(该方法的模拟在第二解中有所提示)

那么该题目还可以通过另一种方式来完成,这是一个重复的扁平化过程,含有子指针的双向链表的未结点会指向当前节点下一个节点,当前节点指向孩子节点的双向链表,重复扁平化处理双向链表即可,我们可以通过一个方法来模拟这个过程 // 传入一个头节点,返回一个扁平化后的未结点 //。

最后一种方式,是借助栈的特性(先进后出)用来模拟递归行为,栈可以帮助我们记录节点,先处理 child 链表,再处理 next 链表。当处理完 child 后,将 next 节点推入栈,以便之后继续处理。

代码示例:

Node* flattenList(Node* head)

{

Node *tmp = head ;

while (tmp)

{

if (tmp -> child)

{

Node *phead = tmp -> child ;

Node *ptail = flattenList(phead) ;

ptail -> next = tmp -> next ;

if (tmp -> next)

{

tmp -> next -> prev = ptail ;

}

tmp -> next = phead ;

phead -> prev = tmp ;

tmp -> child = nullptr ;

}

tmp = tmp -> next ;

}

tmp = head ;

while (tmp -> next) tmp = tmp -> next ;

return tmp ;

}

完整代码

cpp 复制代码
// 方法二
class Solution {
    // 传入一个头节点,返回一个扁平化后的未结点
    Node* flattenList(Node* head)
    {
        Node *tmp = head ;
        while (tmp)
        {
            if (tmp -> child)
            {
                Node *phead = tmp -> child ;
                Node *ptail = flattenList(phead) ;

                ptail -> next = tmp -> next ;
                if (tmp -> next)
                {
                    tmp -> next -> prev = ptail ;
                }
                tmp -> next = phead ;
                phead -> prev = tmp ;

                tmp -> child = nullptr ;
            }
            tmp = tmp -> next ;
        }
        tmp = head ;
        while (tmp -> next) tmp = tmp -> next ;
        return tmp ;

    }
public:
    Node* flatten(Node* head) {
        if (head == nullptr)
        {
            return head;
        }
        flattenList(head) ;  
        return head ; 
    }
};
python 复制代码
"""
# Definition for a Node.
class Node:
    def __init__(self, val, prev, next, child):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child
"""
def flattenList(head) :
        if not head : 
            return head
        tmp = head
        while tmp :
            if tmp.child : 
                phead = tmp.child
                ptail = flattenList(phead)

                ptail.next = tmp.next
                if tmp.next : 
                    tmp.next.prev = ptail
                tmp.next = phead
                phead.prev = tmp
                tmp.child = None
            tmp = tmp.next
        while head and head.next :
            head = head.next
        return head
class Solution:
    def flatten(self, head: 'Optional[Node]') -> 'Optional[Node]':
        if not head :
            return head
        flattenList(head)
        return head
cpp 复制代码
// 方法三

class Solution {
public:
    Node* flatten(Node* head) {
        if (!head) return nullptr ;
        stack <Node*> stack ;
        auto curr = head ;

        while (curr)
        {
            if (curr -> child)
            {
                if (curr -> next)
                {
                    stack.push(curr -> next) ;
                }
                curr -> next = curr -> child ;
                curr -> child -> prev = curr ;
                curr -> child = nullptr ;
            }

            if (!curr -> next && !stack.empty())
            {
                curr -> next = stack.top() ;
                stack.pop() ;
                curr -> next -> prev = curr ;
            }
            curr = curr -> next ;
        }
        return head ;
    }
};
python 复制代码
# 方法三 - 栈(stack)python
"""
# Definition for a Node.
class Node:
    def __init__(self, val, prev, next, child):
        self.val = val
        self.prev = prev
        self.next = next
        self.child = child
"""

class Solution:
    def flatten(self, head: 'Optional[Node]') -> 'Optional[Node]':
        if not head :
            return None
        stack = []
        curr = head

        while curr :
            if curr.child :
                if curr.next :
                    stack.append(curr.next)
                curr.next = curr.child
                curr.child.prev = curr
                curr.child = None
            if not curr.next and stack :
                curr.next = stack.pop()
                curr.next.prev = curr
            curr = curr.next
        return head
        
相关推荐
Lbs_gemini06031 小时前
C++研发笔记14——C语言程序设计初阶学习笔记12
c语言·开发语言·c++·笔记·学习
MC何失眠1 小时前
vulnhub靶场【哈利波特】三部曲之Fawkes
网络·python·学习·网络安全
被制作时长两年半的个人练习生3 小时前
【pytorch】pytorch的缓存策略——计算机分层理论的另一大例证
人工智能·pytorch·python
霖大侠3 小时前
Adversarial Learning forSemi-Supervised Semantic Segmentation
人工智能·算法·机器学习
卖个几把萌3 小时前
【06】Selenium+Python 定位动态ID
python·selenium·测试工具
天冬忘忧3 小时前
Flink四大基石之CheckPoint(检查点) 的使用详解
大数据·python·flink
Dwlufvex3 小时前
python selenium(4+)+chromedriver最新版 定位爬取嵌套shadow-root(open)中内容
python·selenium
阿华的代码王国3 小时前
【算法】——前缀和(矩阵区域和详解,文末附)
java·开发语言·算法·前缀和
Sunyanhui14 小时前
力扣 LCR训练计划2(剑指 Offer 22. 链表中倒数第k个节点)-140
算法·leetcode·链表
yours_Gabriel4 小时前
【力扣】3274. 检查棋盘方格颜色是否相同
算法·leetcode