剑指offer-链表专题
06.从尾到头打印链表
**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
ArrayList<Integer> tmp=new ArrayList<Integer>();
public int[] reversePrint(ListNode head) {
lh(head);
int[] res=new int[tmp.size()];
for(int i=0;i<res.length;i++){
res[i]=tmp.get(i);
}
return res;
}
public void lh(ListNode head){
if(head==null) return;
lh(head.next);
tmp.add(head.val);
}
}
思考
首先从尾到头打印,考虑递归,要求返回数组,但不知道链表长度,利用ArrayList存储中间结果,最后返回数组。
24.反转链表
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur =head;
ListNode pre=null;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}
思考
在遍历链表时,将当前节点的指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。
35.复杂链表的复制
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
//解题之前,先回忆下单向链表的克隆(这里的克隆指的是深拷贝)
//单向链表很简单,遍历一遍链表,不断new出新节点赋值即可
//但是在带有随机指针的链表中,稍微有些复杂
//克隆过程中需要创建新节点,并建立新节点之间的连接,同时也需要复制随机指针的关系
class Solution {
Map<Node,Node> hNode=new HashMap<Node,Node>();
public Node copyRandomList(Node head) {
if(head==null) return null;
if(!hNode.containsKey(head)){
Node newHead=new Node(head.val);
hNode.put(head,newHead);
newHead.next=copyRandomList(head.next);
newHead.random=copyRandomList(head.random);
}
return hNode.get(head);
}
}
思考
解题之前,先回忆下单向链表的克隆(这里的克隆指的是深拷贝)单向链表很简单,遍历一遍链表,不断new出新节点赋值即可。
但是在带有随机指针的链表中,稍微有些复杂克隆过程中需要创建新节点,并建立新节点之间的连接,同时也需要复制随机指针的关系。
通过递归new出新节点,回溯判断节点是否存在,HashMap创建两个你节点之间的联系方便获取。