题目:复制含有随机指针节点的链表
描述:有一种链表节点类描述如下:
public class Node {
public int value;
public Node next;
public Node rand;
public Node(int data){
this.value = data;
}
}
Node 类中的value是节点值,next指针和正常单链表中next指针的意义一样,都指向下一个节点,rand指针是Node类中新增的指针,这个指针可能指向链表中的任意一个节点,也可能指向null。
给定一个由Node节点类型组成的无环单链表的头节点head,请实现一个函数完成这个链表中所有结构的复制,并返回复制的新链表的头结点。例如链表 1 —> 2 —>3 —> null,假如:1的rand指针指向3,2的rand指针指向null,3的rand指针指向 1,复制后的链表也应该具有这种关系
思路:
方法一:描述对应关系,可以考虑散列表
1) 从左到右遍历链表,对每个节点都生成对应的副本节点,然后将对对应关系放入哈希map中
步骤:
1 完成后,原链表没有任何变化,每一个副本节点的next和rand指针都指向null
2.再从左到右遍历链表,此时就可以设置每一个副本节点的rend和next指针
例如:原链表 1 —>2 —>3 —>null,假设1的rand指针指向3,2的rand指针指向null,3的rand指针指向1.遍历到1节点的时候,可以从map中得到1的副本节点1’ ,1的next指向2 ,所以从map中找到2的副本 2’,令1’->2’,同时指定1’的rand指针指向
3.经过两次遍历之后,返回散列表中 key = head 的值即可
代码实现:
private static Node copyChain(Node head) {
HashMap<Node,Node> map = new HashMap();
Node cur = head;
while(cur != null){
map.put(cur,new Node(cur.value));
cur = cur.next;
}
cur = head;
while (cur != null){
map.get(cur).next = map.get(cur.next);
map.get(cur).rand = map.get(cur.rand);
cur = cur.next;
}
return map.get(head);
}
方法二:用有限的变量去完成该功能
1) 从左到右遍历链表,把每个节点cur都复制一份copy,然后把copy放在cur和下一个要遍历的节点中间 1—>1’—>2—>2’—>3—>3’
2)再从左到右遍历链表,在遍历时设置每一个副本节点的rand
3)步骤2完成之后,节点1,2,3之间的rand没有变化,而节点1’ 2’ 3’之间的rand关系也被正确设置了,只要将其分离即可
代码实现:
private static Node copyChain(Node head) {
if (head == null) {
return null;
}
Node cur = head;
Node next = null;
// 复制节点
while (cur != null) {
next = cur.next;
cur.next = new Node(cur.value);
cur.next.next = next;
}
cur = head;
Node curCopy = null;
// 设置复制节点的rand指针
while (cur != null) {
next = cur.next.next;
curCopy = cur.next;
curCopy.rand = cur.rand != null ? cur.rand.next : null;
cur = next;
}
Node res = head.next;
cur = head;
//拆分
while (cur != null){
next = cur.next.next;
curCopy = cur.next;
cur.next = next;
curCopy.next = next != null ? next.next:null;
cur = next;
}
return res;
}
题目:两个单链表生成相加链表
问题描述:
假设链表中的每一个节点的值都在0-9之间,那么链表整体就可以代表一个整数,例如9 -> 3 ->7,可以代表937,给定这两种链表的头节点head1和head2,请生成代表两个数相加值的结果链表
思路:
可以对链表求其逆序链表,求完之后,将两数相加,给定一个是否进位的进位标值sign,即可。
代码实现:
public class AddChain {
public static void main(String[] args) {
// init()
Node head1 = new Node(9);
Node node1 = new Node(3);
Node node2 = new Node(7);
Node head2 = new Node(6);
Node node3 = new Node(3);
head1.next = node1;
node1.next = node2;
head2.next = node3;
Node reHead1 = ReverNode(head1);
Node reHead2 = ReverNode(head2);
Node res = add(reHead1, reHead2);
res = ReverNode(res);
Node h = res;
while (h != null) {
System.out.print(h.value + " ");
h = h.next;
}
}
private static Node add(Node head1, Node head2) {
Node head = new Node(0);
Node h = head;
int ca = 0;
while (head1 != null && head2 != null) {
int res = head1.value + head2.value + ca;
ca = 0;
if (res > 9) {
res = res - 10;
ca++;
}
h.next = new Node(res);
h = h.next;
head1 = head1.next;
head2 = head2.next;
}
while (head1 != null) {
int res = head1.value + ca;
ca = 0;
if (res > 9) {
res = res - 10;
ca++;
}
h.next = new Node(res);
h = h.next;
head1 = head1.next;
}
while (head2 != null) {
int res = head2.value + ca;
ca = 0;
if (res > 9) {
res = res - 10;
ca++;
}
h.next = new Node(res);
h = h.next;
head2 = head2.next;
}
if(ca != 0){
h.next = new Node(ca);
h = h.next;
}
return head.next;
}
private static Node ReverNode(Node head) {
Node next = null;
Node pre = null;
while (head != null) {
next = head.next;
head.next = pre;
pre = head;
head = next;
}
return pre;
}
}