一、题目大意
反转一个单链表,实现递归和非递归两种形式
二、链表节点
public class ListNode {
int val;
ListNode next;
public ListNode(int val) {
this.val = val;
}
}
三,分析
1,非递归解决方案:最容易想到的是使用三个指针,p1,p2,p3,遍历链表事项反转。
(这里需要注意的是,p1,p2,p3的初始化,不同初始化应该考虑链表头的不同处理。一般的初始是p1为空,下面讨论)
2,递归解决方案:每次考虑后面节点已经反转过了
3,插入反转:从第二个开始,把后面的一个节点放在head节点的后面,最后再把第一个节点放在最后。
四、边界处理
if (head == null || head.next == null) {
return head;
}
五、代码
1,三个指针
public static ListNode reverseList1(ListNode head) {
if(head == null || head.next == null) {//边界处理
return head;
}
ListNode p1 = null;//初始化
ListNode p2 = head;
ListNode p3 = head.next;
while(p3 != null) {//反转过程
p2.next = p1;
p1 = p2;
p2 = p3;
p3 = p3.next;
}
p2.next = p1;
head = p2;
return head;
}
2,递归:
public static ListNode reverseList2(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode p = head.next;
ListNode n = reverseList2(p);//递归
head.next = null;
p.next = head;
return n;
}
3,插入法
public static ListNode reverseList3(ListNode head) {
if (head == null || head.next == null) {//边界处理
return head;
}
ListNode p = head.next;
ListNode q = null;
while(p.next != null) {//第二个节点开始,后面的节点插入到head的后面
q = p.next;//或得节点
p.next = q.next;
q.next = head.next;//插入到head的后面
head.next = q;
}
p.next = head;//形成环
head = p.next.next;//把第一个节点放在最后
p.next.next = null;//断开环
return head;
}