深度拷贝带随机指针的链表代码2优化
使用HasnMap的方式
不使用HashMap的方式
深度拷贝带随机指针的链表:
时间复杂度:O(n),虽然有两个循环,但是没有嵌套,因此是O(2n) => O(n)
空间复杂度:O(n),因为用到了hashmap来存储random指针,深拷贝,因此拷贝所占用的空间不计
因此优化成不使用HashMap的方式
public class Test2 {
public static class ListNode {
Object value;
ListNode next;
ListNode random;
public ListNode(Object value, ListNode next, ListNode random) {
this.value = value;
this.next = next;
this.random = random;
}
public ListNode(Object value) {
this.value = value;
}
@Override
public String toString() {
return "ListNode{" +
"value=" + value +
", next=" + next +
", random=" + random +
'}';
}
public void setRandom(ListNode random) {
this.random = random;
}
}
/**
* 深度拷贝带随机指针的链表
*
* @param head
* @return
*/
public static ListNode copyRandomList(ListNode head) {
if (head == null) {//规范的代码都会做防空判断
return head;
}
copyValue(head);
copyRandom(head);
return split(head);
}
/**
* 复制链表value
* 原链表node(n) next指向复制后的node(n`),复制后的node(n`) next指向node(n+1),n为下标
*
* @param head
*/
public static void copyValue(ListNode head) {
ListNode node = head;
while (node != null) {
ListNode copy = new ListNode(node.value);
copy.next = node.next;
node.next = copy;
node = copy.next;
}
}
/**
* 复制链表random
* 原链表node(n) next指向复制后的node(n`),复制后的node(n`) next指向node(n+1),n为下标,根据对应next 来copy random
*
* @param head
*/
private static void copyRandom(ListNode head) {
ListNode node = head;
while (node != null && node.next != null) {
if (node.random != null) {
node.next.random = node.random.next;
}
node = node.next.next;
}
}
/**
* 拆分
* 原链表node(n) next指向复制后的node(n`),复制后的node(n`) next指向node(n+1),n为下标,根据next next来进行拆分
*
* @param head
* @return
*/
private static ListNode split(ListNode head) {
ListNode result = head.next;//head.next就是拷贝后的头节点,即1`
ListNode move = head.next;
while (head != null && head.next != null) {
head.next = head.next.next;
head = head.next;
if (move != null && move.next != null) {
move.next = move.next.next;
move = move.next;
}
}
return result;
}
public static void main(String[] args) {
ListNode node6 = new ListNode(66, null, null);
ListNode node5 = new ListNode(55, node6, null);
ListNode node4 = new ListNode(44, node5, null);
ListNode node3 = new ListNode(33, node4, node5);
ListNode node2 = new ListNode(22, node3, null);
ListNode node1 = new ListNode(11, node2, node6);
// node6.setRandom(node1);//toString会死循环,因此不加,已经可以完成深度拷贝
System.out.println(node1);//ListNode{value=11, next=ListNode{value=22, next=ListNode{value=33, next=ListNode{value=44, next=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}, random=null}, random=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}}, random=null}, random=ListNode{value=66, next=null, random=null}}
ListNode copyRandomList = copyRandomList(node1);
System.out.println(copyRandomList);//ListNode{value=11, next=ListNode{value=22, next=ListNode{value=33, next=ListNode{value=44, next=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}, random=null}, random=ListNode{value=55, next=ListNode{value=66, next=null, random=null}, random=null}}, random=null}, random=ListNode{value=66, next=null, random=null}}
}
}