反转链表
要求我们不分配额外的空间,使链表进行反转。
题目分析
链表的节点结构如下:
class ListNode {
int val;
ListNode next;
ListNode() {}
ListNode(int val) { this.val = val; }
ListNode(int val, ListNode next) { this.val = val; this.next = next; }
先来进行简单的分析
如果我们现在有一个简单的链表,只包含两个节点,如下图:
如果我们要对这个简单的链表进行反转需要两步:
- 将节点2的next指针指向节点1
- 将节点1的next指针置空
如果节点数增加一个呢?如下图:
我们对这个三个节点的链表进行反转也大同小异都是这个思路:
将当前节点的下一个节点的next指针指向自己,将自己的next指针置空
但是,当链表的节点数大于2时,我们就不能简单的从头节点开始进行操作了,而是应该找到尾节点,从尾节点开始开始那两步操作。为什么需要从尾节点开始呢?
就拿刚才的三个节点的链表举例,如果我们从头节点开始操作,那么第二个节点的next指针指向了头节点,我们就找不到第三个节点了!可以看下图:
代码实现
有了刚才的分析,我们也就有了思路
public static ListNode reversList (ListNode head){
// 如果当前节点为null或者此节点为尾节点就反回
if(head==null || head.next==null){
return head;
}
// 采用递归来寻找尾节点,上面的那个判断可以保证当找到尾节点时,返回尾节点
ListNode last=reversList(head.next);
// 当找到尾节点时,head节点为尾节点前一个节点,因为使用了递归
// 进行两部操作
head.next.next=head;
head.next=null;
return last;
}
这样,我们就成功的将链表进行了反转!
测试结果
public static void main(String[] args) {
ListNode l1=new ListNode(1);
ListNode l2=new ListNode(2);
ListNode l3=new ListNode(3);
ListNode l4=new ListNode(4);
l1.next=l2;
l2.next=l3;
l3.next=l4;
System.out.println("原链表:"+l1.toString());
ListNode listNode = reversList(l1);
System.out.println("反转链表:"+listNode.toString());
}
结果:
原链表:{"val":1,"next":{"val":2,"next":{"val":3,"next":{"val":4,"next":null}}}}
反转链表:{"val":4,"next":{"val":3,"next":{"val":2,"next":{"val":1,"next":null}}}}