力扣剑指offer 第2天 链表(简单) 剑指 Offer 06. 从尾到头打印链表 剑指 Offer 24. 反转链表 剑指 Offer 35. 复杂链表的复制
剑指 Offer 06. 从尾到头打印链表
思路
用链表存储每一个节点,然后逆序放入数组中
注意
这一题会传入 [] 空数组数据,因此需要判断head是否为null,如果为null则返回空数组[]
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public int[] reversePrint(ListNode head) {
if(head==null)return new int[]{};
LinkedList<ListNode>list=new LinkedList<>();
ListNode p = head;
while (p.next!=null){
ListNode t = p;
list.push(t);
p = p.next;
}
list.push(p);
int[] ans = new int[list.size()];
for(int i=list.size()-1;i>=0;i--){
ans[i]=list.get(i).val;
}
return ans;
}
}
剑指 Offer 24. 反转链表
题意
将整个链表逆转,并返回逆转后的链表头结点
思路
- 特判head是否为空,为空直接返回head
- 使用三个节点指针分别记录 last=null cur=head next=head.next
- 如果next节点存在则更新last,cur,next(先将cur.next=last逆转指针)
- 当next=null时已经跳出while可此时的cur的next还未更新,所以更新它cur.next=last
- 返回cur(当前节点便是新的头结点)
代码
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null)return null;
ListNode last=null,next=head.next,cur=head;
while (next!=null){
cur.next = last;
last = cur;
cur = next;
next = next.next;
}
cur.next = last;
return cur;
}
}
剑指 Offer 35. 复杂链表的复制
题意
完全的复刻复杂链表,不可以引用原本的节点!必须自己new节点!难点在于随机指针。
思路
- 如果head为空返回null
- new一个新节点headNode作为复刻链表的头节点
- 创建两个动态数组l1,l2分别用来存放旧链表与新链表
- 如何存在下一个节点则循环遍历并复刻当前节点,同时将上一个复刻节点的next指向当前复刻节点
- 遍历l1,用indexOf()方法找出对应的random所在的节点下标(random为null的时候跳过判断),然后将对应l2中的节点的random设置为l2下的对应下标的节点
- 返回headNode复刻链表的头结点
代码
/*
// 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;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if(head==null)return null;
final Node headNode = new Node(head.val);
ArrayList<Node> l1 = new ArrayList<>(),l2=new ArrayList<>();
l1.add(head);l2.add(headNode);
while (head.next!=null){
head = head.next;
final Node node = new Node(head.val);
l2.get(l2.size()-1).next = node;//将上一个新节点的next指向当前生成的新节点
l1.add(head);l2.add(node);
}
//遍历l1找它们的random在的下标(null则跳过)
int size = l1.size();
for (int i=0;i<size;i++) {
if(l1.get(i).random!=null){
l2.get(i).random = l2.get(l1.indexOf(l1.get(i).random));
}
}
return headNode;
}
}