码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode 剑指 Offer 35. 复杂链表的复制

时间:2020-07-07 13:26:38      阅读:57      评论:0      收藏:0      [点我收藏+]

标签:let   mpp   script   oid   temp   shm   tco   string   new   

package com.example.lettcode.offer;

import java.util.HashMap;
import java.util.Map;

/**
 * @Class CopyRandomList
 * @Description  剑指 Offer 35. 复杂链表的复制
 * 请实现 copyRandomList 函数,复制一个复杂链表。
 * 在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,
 * 还有一个 random 指针指向链表中的任意节点或者 null。
 *
 * 提示:
 * -10000 <= Node.val <= 10000
 * Node.random 为空(null)或指向链表中的节点。
 * @Author
 * @Date 2020/7/6
 **/
public class CopyRandomList {
    static class Node {
        int val;
        Node next;
        Node random;

        public Node(int val) {
            this.val = val;
            this.next = null;
            this.random = null;
        }
    }   
}
/**
 * 解法1: 先逐个设置复制链表每个节点的next指针
 *       再设置每个节点的random指针,复制random指针时,都需要从头结点还是寻找
 */
public static Node copyRandomList(Node head) {
	if (head == null) return head;
	Node p = head;
	Node neHead = new Node(head.val);
	Node q = neHead;
	// 先找到对应的next
	while (p != null) {
		Node node = new Node(p.val);
		q.next = node;
		q = q.next;
		p = p.next;
	}

	p = head;
	q = neHead.next;
	// 再设置复制链表的random指针
	while (p != null) {
		Node tempP = head;
		Node tempQ = neHead.next;
		// random 需要从头开始重新遍历
		while (tempP != p.random && tempP != null) {
			tempP = tempP.next;
			tempQ = tempQ.next;
		}
		q.random = tempQ;
		p = p.next;
		q = q.next;
	}
	return neHead.next;
}
/**
 * 解法2: 利用HashMap,保存每个节点和其对应的复制节点,以便next和random指针可以直接
 */
public static Node copyRandomList(Node head) {
	if (head == null) return head;
	Map<Node, Node> nodeNodeMap = new HashMap<>();
	Node node = head;
	while (node != null) {
		nodeNodeMap.put(node, new Node(node.val));
		node = node.next;
	}
	/* 方式1
	//复制结点指向
	node = head;
	while (node != null) {
		//新结点next指向同旧结点的next指向
		nodeNodeMap.get(node).next = nodeNodeMap.get(node.next);
		//新结点random指向同旧结点的random指向
		nodeNodeMap.get(node).random = nodeNodeMap.get(node.random);
		node = node.next;
	}
	// 返回旧链表head 所对应的复制结点
	return nodeNodeMap.get(head);*/

	// 方式2
	node = head;
	// 注释的这一行新建了一个头结点,导致这个头结点的random是null,
	// 并非是nodeNodeMap 中head节点对应的复制后的头结点
	// Node newHead = new Node(head.val);
	Node newHead = nodeNodeMap.get(head);
	Node cur = newHead;
	while (node != null) {
		cur.next = nodeNodeMap.get(node.next);
		cur.random = nodeNodeMap.get(node.random);
		node = node.next;
		cur = cur.next;
	}
	return newHead;
}
// 测试用例
public static void main(String[] args) {
	Node head = new Node(7);
	Node node11 = new Node(13);
	head.next = node11;
	node11.random = head;
	Node node12 = new Node(11);
	node11.next = node12;
	Node node13 = new Node(10);
	node12.next = node13;
	node13.random = node12;
	Node node14 = new Node(1);
	node13.next = node14;
	node12.random = node14;
	node14.random = head;
	Node copyHead = copyRandomList(head);
	System.out.println("");
}

leetcode 剑指 Offer 35. 复杂链表的复制

标签:let   mpp   script   oid   temp   shm   tco   string   new   

原文地址:https://www.cnblogs.com/fyusac/p/13259933.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!