复制带随机指针的链表【php版】

复制带随机指针的链表【php版】
以下提供三种方法
方法1 :先将所有结点copy一份,再遍历原链表,将next,random之类的指向还原
方法2 :dfs法,有点类似方法1,但只遍历原链表一遍
方法3 :迭代 + 节点拆分

/**
 * Definition for a Node.
 * class Node {
 *     public $val = null;
 *     public $next = null;
 *     public $random = null;
 *     function __construct($val = 0) {
 *         $this->val = $val;
 *         $this->next = null;
 *         $this->random = null;
 *     }
 * }
 */

class Solution {
	/**
	 * @param Node $head
	 * @return Node
	 */
	function copyRandomList($head) {
		if (is_null($head)) {
			return $head;
		}
		$h = $head;
		$nodeArr = [];
		while ($h) {
			$nodeArr[spl_object_id($h)] = new ListNode($h->val);
			$h = $h->next;
		}
		$t = $head;
		$headNode = new ListNode(0);
		$headNode->next = $nodeArr[spl_object_id($t)];
		while ($t) {
			$newNode = $nodeArr[spl_object_id($t)];
			if (is_null($t->next)) {
				$newNode->next = null;
			} else {
				$newNode->next = $nodeArr[spl_object_id($t->next)];
			}

			if (is_null($t->random)) {
				$newNode->random = null;
			} else {
				$newNode->random = $nodeArr[spl_obj_id($t->random)];
			}
			$t = $t->next;
		}

		return $headNode->next;
	}
	function copyRandomListV2($head) {
		static $nodeArr = [];
		if (is_null($head)) {
			return null;
		}
		if (!array_key_exists(spl_object_id($head), $nodeArr)) {
			$newNode = new ListNode($head->val);
			$nodeArr[spl_object_id($head)] = $newNode;
			$newNode->next = $this->copyRandomListV2($head->next);
			$newNode->random = $this->copyRandomListV2($head->random);
		}
		return $nodeArr[spl_object_id($head)];
	}

	function copyRandomListV3($head) {
		if (is_null($head)) {
			return null;
		}
		$h = $head;
		while ($h) {
			$newNode = new ListNode($h->val);
			$newNode->next = $h->next;
			$h->next = $newNode;
			$h = $h->next->next;
		}
		$h = $head;
		while ($h && $h->next) {
			$newNode = $h->next;
			$newNode->random = $h->random ? $h->random->next : null;
			$h = $h->next->next;
		}
		$res = $head->next;
		$h = $head;
		while ($h) {
			$newNode = $h->next;
			if ($newNode->next) {
				$h->next = $newNode->next;
				$newNode->next = $newNode->next->next;
			} else {
				$newNode->next = null;
				$h->next = null;
			}
			$h = $h->next;
		}
		return $res;
	}
}
上一篇:LinkedList源码分析(四)


下一篇:ArrayList和LinkedList源码分析