zoukankan      html  css  js  c++  java
  • [LeetCode] 138. 复制带随机指针的链表

    题目链接 : https://leetcode-cn.com/problems/copy-list-with-random-pointer/

    题目描述:

    给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

    要求返回这个链表的深拷贝

    示例:

    示例:

    输入:
    {"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
    
    解释:
    节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
    节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。
    

    提示:

    你必须返回给定头的拷贝作为对克隆列表的引用。

    思路:

    思路一: 可以套用与 133. 克隆图|题解链接一样方法两种遍历(DFS, BFS)

    思路二: 因为是链表,所以直接先把所有节点找到, 再连线;

    思路三:

    这个方法十分巧妙 , 用图说明吧

    1563690472002

    代码:

    思路一: DFS

    """
    # Definition for a Node.
    class Node:
        def __init__(self, val, next, random):
            self.val = val
            self.next = next
            self.random = random
    """
    class Solution:
        def copyRandomList(self, head: 'Node') -> 'Node':
            lookup = {}
            def dfs(head):
                if not head: return None
                if head in lookup: return lookup[head]
                clone = Node(head.val, None, None)
                lookup[head] = clone 
                clone.next, clone.random = dfs(head.next), dfs(head.random)
                return clone
            return dfs(head)
    

    BFS

    """
    # Definition for a Node.
    class Node:
        def __init__(self, val, next, random):
            self.val = val
            self.next = next
            self.random = random
    """
    class Solution:
        def copyRandomList(self, head: 'Node') -> 'Node':
            from collections import deque
            lookup = {}
        
            def bfs(head):
                if not head: return head
                clone = Node(head.val, None, None)
                queue = deque()
                queue.appendleft(head)
                lookup[head] = clone
                while queue:
                    tmp = queue.pop()
                    if tmp.next and tmp.next not in lookup:
                        lookup[tmp.next] = Node(tmp.next.val, [], [])
                        queue.appendleft(tmp.next)  
                    if tmp.random and tmp.random not in lookup:
                        lookup[tmp.random] = Node(tmp.random.val, [], [])
                        queue.appendleft(tmp.random)
                    lookup[tmp].next = lookup.get(tmp.next)
                    lookup[tmp].random = lookup.get(tmp.random)
                return clone
            return bfs(head)
    

    思路二:

    """
    # Definition for a Node.
    class Node:
        def __init__(self, val, next, random):
            self.val = val
            self.next = next
            self.random = random
    """
    class Solution:
        def copyRandomList(self, head: 'Node') -> 'Node':
            if not head: return None
            lookup = {}
            node = head
            # 创建所有节点
            while node:
                lookup[node] = Node(node.val, None, None)
                node = node.next
            
            node = head
            # 节点连接
            while node:
                lookup[node].next = lookup.get(node.next)
                lookup[node].random = lookup.get(node.random)
                node = node.next
            return lookup[head]
    

    java

    class Solution {
        public Node copyRandomList(Node head) {
            if (head == null) return null;
            Map<Node, Node> lookup = new HashMap<>();
            Node node = head;
            while (node != null){
                lookup.put(node, new Node(node.val, null, null));
                node = node.next;
            }
            node = head;
            while (node != null){
                lookup.get(node).next = lookup.get(node.next);
                lookup.get(node).random = lookup.get(node.random);
                node = node.next;
            }
            return lookup.get(head);
        }
    }
    

    思路三:

    """
    # Definition for a Node.
    class Node:
        def __init__(self, val, next, random):
            self.val = val
            self.next = next
            self.random = random
    """
    class Solution:
        def copyRandomList(self, head: 'Node') -> 'Node':
            if not head: return None
            # 复制节点
            cur = head
            while cur:
                # 保存下一个节点
                tmp = cur.next
                # 后面跟着同样的节点
                cur.next = Node(cur.val, None, None)
                # 拼接
                cur.next.next = tmp
                cur = tmp
            # 复制random指针
            cur = head
            while cur:
                if cur.random:
                    cur.next.random = cur.random.next
                cur = cur.next.next
            # 拆分
            cur = head
            copy_head = head.next
            copy_cur = copy_head
            while copy_cur.next:
                # 组head
                cur.next = cur.next.next
                cur = cur.next
                # 组 copy_head
                copy_cur.next = copy_cur.next.next
                copy_cur = copy_cur.next
            # 把链表结束置空
            cur.next = copy_cur.next
            copy_cur.next = None
            return copy_head
    

    java

    class Solution {
        public Node copyRandomList(Node head) {
            if (head == null) return null;
            // 复制
            Node cur = head;
            while (cur != null) {
                Node tmp = cur.next;
                cur.next = new Node(cur.val, null, null );
                cur.next.next = tmp;
                cur = tmp;
            }
            // 置随机指针
            cur = head;
            while (cur != null) {
                if (cur.random != null) cur.next.random = cur.random.next;
                cur = cur.next.next;
            }
            // 拆分
            cur = head;
            Node copy_head = cur.next;
            Node copy_cur = copy_head;
            while (copy_cur.next != null) {
                cur.next = cur.next.next;
                cur = cur.next;
    
                copy_cur.next = copy_cur.next.next;
                copy_cur = copy_cur.next;
            }
            // 结束标志null
            cur.next = null;
            return copy_head;
        }
    }
    
  • 相关阅读:
    MySQL length函数
    MySQL between ... and ...
    MySQL Group By使用
    MySQL 聚合函数/分组函数
    MySQL where与like
    MySQL order by与distinct
    城市网络
    滑动窗口
    合并回文子串(NC13230)
    NC50439
  • 原文地址:https://www.cnblogs.com/powercai/p/11223066.html
Copyright © 2011-2022 走看看