LeetCode 138:ランダムポインタとコピーのコピーリストのランダムポインタリスト

リストを考えると、各ノードは、リンクリストのノードまたは空の内の任意のノードを指すことができ、ランダムな追加のポインタが含まれています。

彼はのリストに戻るに頼ま深いコピー

リンクされたリストは、各ノードがリストまたはヌル内の任意のノードを指すことができ、追加のランダムポインタを含むように与えられます。

戻り深いコピーリストのを。

例:

IMG

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

ヒント:

  1. あなたは返さなければならない与えられたコピーの先頭にリストのクローンへの参照として。

注意:

  1. あなたは返さなければならない与えられた頭部のコピーをクローン化されたリストへのリファレンスとして。

問題解決のアイデア:

ランダムポインタを考慮する必要性に起因する、ランダムなノードへのポインタはNULLであってもよいし、深いコピーの下で、あなたはランダムにリストの元のリストに新しいノードポイントへのポインタができないので、私は、新しいリストを乗り越えることができない、リストの最後のノードであってもよいです。

一時的にデータ構造体に格納され、再度コピーノードを見つけるために、データ構造をトラバースつすべてのノードをコピーすることで2種類の方法を、解決、ポインタがランダムに方向付け決定されます。各ノードは、あなたがO(n)との合計時間の複雑さを置くことができるようにハッシュテーブル(辞書)の使用は、その複雑さはO(1)で検索した場合、ランダムなノードポインタを見つける必要があるため、一時的なストレージノードに起因するすべての、空間的複雑さはO(N)です。

別の解決方法は、ように、最初のノードの各々は、単にコピーされ、コピーされたノードは、元のノードの背面に接続され、そして、得られた3つの結果を横断する必要があることです。関係無作為に細分化ノードリストを決定した後。それは非常に巧妙なアイデアです:

元のリスト:> 3 1-> 2-
1-> 1-> 2-> 2-> 3-> 3:背面各ノードの元のノードにコピーされた
コピー関係ポインタランダム
スプリットリスト:1-> 2- > 3> 3、1-> 2-

ランダム複製へのポインタは、ノードの元のランダムなノード1つのノードがランダムに新しいノードである場合。1-> 2-> 3後、ランダムなノード3、ノード複製::場合、元のリスト1-> 1-> 2-> 2-> 3-> 3であります

我々は、単に新しいノード点(元のノード1後ノード1)ノードの元のノードのランダムなノードの後に(元のノード3のランダムなノード、及びランダムなノードのノード3がまだ3た後コピーした後、しかしこのノード)は、新しいノードであり、最終的には(リストの分割は、ノード点間の関係には影響しません)リストを分割します。その時間複雑性はO(N)であり、空間的複雑さはO(1)です。

最初の方法:

Javaの:

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return null;
        HashMap<Node, Node> map = new HashMap<>();//借助hashMap
        Node newHead = new Node(0);//虚拟头节点
        Node cur = newHead;//指针指向当前节点
        Node tmp;
        while (head != null) {
            if (map.containsKey(head)) {//查询原节点是否已存在于map
                tmp = map.get(head);//如果存在直接取value值
            } else {
                tmp = new Node(head.val);//不存在则新建一个值相同的节点
                map.put(head, tmp);//存入map,key为原节点,value为新节点
            }
            cur.next = tmp;
            if (head.random != null) {//原节点的随机节点不为空的情况下
                if (map.containsKey(head.random)) {//查询该随即节点是否已存在于map
                    tmp.random = map.get(head.random);//存在则直接将新节点的随机指针指向其value值
                } else {
                    tmp.random = new Node(head.random.val);//不存在则新建一个值相同的随机节点
                    map.put(head.random, tmp.random);//存入map,key为原节点的随机节点,value为新节点的随机节点
                }
            }
            head = head.next;//刷新原链表当前头节点
            cur = tmp;//即cur=cur.next,刷新新链表当前节点
        }
        return newHead.next;
    }
}

python3:

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head: return None
        map = {}
        newHead = Node(val=0, next=None, random=None)
        cur = newHead
        while head:
            if head in map.keys():
                tmp = map.get(head)
            else:
                tmp = Node(val=head.val, next=None, random=None)
                map.setdefault(head, tmp)
            cur.next = tmp
            if head.random:
                if head.random in map.keys():
                    tmp.random = map.get(head.random)
                else:
                    tmp.random = Node(val=head.random.val, next=None, random=None)
                    map.setdefault(head.random, tmp.random)
            head = head.next
            cur = tmp
        return newHead.next

第二の方法:

Javaの:

class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) return null;
        //复制节点 1->2->3 ==> 1->1->1->2->2->3->3
        Node cur = head;
        while (cur != null) {
            Node next = cur.next;
            Node tmp = new Node(cur.val);
            cur.next = tmp;
            tmp.next = next;
            cur = next;
        }
        //复制随机指针
        cur = head;
        while (cur != null) {
            //cur.next.random=>新节点的随机节点  cur.random.next=>原节点的随机节点的下一个节点
            cur.next.random = cur.random == null ? null : cur.random.next;
            cur = cur.next.next;//链表扩展一倍后肯定是偶数位链表,所以可以直接用cur.next.next
        }
        //分离节点
        cur = head;
        Node newHead = head.next;//新链表头节点
        while (cur != null) {
            Node tmp = cur.next;
            cur.next = tmp.next;
            cur = cur.next;
            tmp.next = cur == null ? null : cur.next;
        }
        return newHead;
    }
}

python3:

class Solution:
    def copyRandomList(self, head: 'Node') -> 'Node':
        if not head: return None
        cur = head
        while cur:
            next = cur.next
            tmp = Node(val=cur.val, next=next, random=None)
            cur.next = tmp
            cur = next
        cur = head
        while cur:
            cur.next.random = cur.random.next if cur.random else None
            cur = cur.next.next
        cur = head
        newHead = head.next
        while cur:
            tmp = cur.next
            cur.next = tmp.next
            cur = cur.next
            tmp.next = cur.next if cur else None
        return newHead

おすすめ

転載: www.cnblogs.com/zhangzhe532/p/11263136.html