Flatten a Multilevel Doubly Linked List

题目.png

解决思路

观察上方的图,每一个child 又是一个同样的结构,递归完成即可,注意递归的返回值应该是最后的节点,针对3节点,调用递归函数返回值应该是10节点,然后才能将10和3节点的下一个(4)节点连接。针对本身单链表,循环解决即可。

思路一

/*
// Definition for a Node.
class Node {
    public int val;
    public Node prev;
    public Node next;
    public Node child;

    public Node() {}

    public Node(int _val,Node _prev,Node _next,Node _child) {
        val = _val;
        prev = _prev;
        next = _next;
        child = _child;
    }
};
*/
class Solution {
    public Node flatten(Node head) {
        if (head == null) return null;
        flatten_recur(head);
        return head;
    }
    
    public Node flatten_recur(Node head) {
        Node cur = head;
        Node previous = null;
        //不能使用cur.next != null, 最后一个也有child
        for (;cur != null;) {
            previous = cur;
            if (cur.child != null) {
                Node temp = cur.next;
                
                Node last = flatten_recur(cur.child);
                
                //注意最后一个有child, 那么last应该是child最后一个
                previous = last;
                
                cur.next = cur.child;
                cur.child.prev = cur;
                cur.child = null;
                
                last.next = temp;
                if (temp != null) {
                    temp.prev = last;
                }
                cur = temp;
            }else {
                cur = cur.next;
            }    
        }
        return previous;
    }
    
}

思路二

看图,其实这个链表(不考虑prev指针)的结构就是二叉树,child 就是左孩子,next 就是右孩子,那连接的双链表其实就是先序遍历。

递归方式:

/*
// Definition for a Node.
class Node {
    public int val;
    public Node prev;
    public Node next;
    public Node child;

    public Node() {}

    public Node(int _val,Node _prev,Node _next,Node _child) {
        val = _val;
        prev = _prev;
        next = _next;
        child = _child;
    }
};
*/
class Solution {
    public Node flatten(Node head) {
        if (head == null) return null;
        flatten_recur(head, null);
        return head;
    }
    
    public Node flatten_recur(Node head, Node last) {
        if (last != null){
           last.next = head; 
        }
        
        Node next = head.next;
        
        head.prev = last;
        Node previous = head;
        
        if (head.child != null) {
            previous = flatten_recur(head.child, previous);
        }
        
        head.child = null;
           
        // 不能直接使用head.next,因为head.next已经改变
        if (next != null) {
            previous = flatten_recur(next, previous);
        }
        
        return previous;
    }
    
}

非递归方式:

/*
// Definition for a Node.
class Node {
    public int val;
    public Node prev;
    public Node next;
    public Node child;

    public Node() {}

    public Node(int _val,Node _prev,Node _next,Node _child) {
        val = _val;
        prev = _prev;
        next = _next;
        child = _child;
    }
};
*/
class Solution {
    public Node flatten(Node head) {
        if (head == null) return null;
        
        Stack stack = new Stack();
        Node cur = head;
        Node previous = null;
        
        while (! stack.empty() || cur != null) {
            while (cur != null) {
                if (previous != null) {
                    previous.next = cur;
                }
                cur.prev = previous;
                
                previous = cur;
                // 由于我们会改变next指针,所以这里不能想正常遍历那样放cur,
                // 对应的,pop后不需要再得到next
                if (cur.next != null) {
                    stack.push(cur.next);
                }                
                cur = cur.child;
                
                //注意这步不能少
                previous.child = null;
            }
            if (! stack.empty()) {
                cur = stack.pop();
            }
        }
        return head;
    }   
}

你可能感兴趣的:(Flatten a Multilevel Doubly Linked List)