返回链表反转后的头结点
需要三个变量。
如果要使cur的指向发生改变,指向它的前一个节点,就需要知道它的前一个节点,但没有指向前一个节点的指针,所以需要用pre来保存前一个节点。然后在交换之前还要用next来保存cur的下一个节点。分为三步,保存next,改变指向,迭代。
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null){
return null;
}
ListNode cur=head;
ListNode pre=null;
ListNode next=null;
while(cur!=null){
next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return pre;
}
}
递归思想
reverseList的作用就是把反转链表然后返回反转链表的头结点。不要进入这个递归里面,脑袋里装不了几个栈,所以应该整体思考。
首先reverse(head.next)这样除了第一个全反转了。然后head.next.next=head,也就是把后一段和前一段连一起了。然后head.next=null,这样就反转过来了,很神奇。
base case就是head.next=null时返回head。
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null)return head;
if(head.next==null)return head;
ListNode last=reverseList(head.next);
head.next.next=head;
head.next=null;
return last;
}
}
返回链表前n个节点反转后的链表
反转前k个,递归实现可以从第二个开始反转第k-1个,但现在不是把head.next变成null,而要变成第k+1个,所以在反转的时候要记录最后那个节点,也就是在返回情况k=1时,记录这个节点的下一个
class Solution {
ListNode next=null;
public ListNode reverseToN(ListNode head,int n){
if(n==1){
next=head.next;
return head;
}
ListNode l= reverseToN(head.next,n-1);
head.next.next=head;
head.next=next;
return l;
}
}
返回链表m到n处反转后的链表
如果m=1,则和反转前k个节点相同,如果m不等于1,则可以看成递归m-1到n,直到m=1.
class Solution {
ListNode next=null;
public ListNode reverseBetween(ListNode head, int left, int right) {
if(left==1){
return reverseToN(head,right);
}
head.next=reverseBetween(head.next,left-1,right-1);
return head;
}
public ListNode reverseToN(ListNode head,int n){
if(n==1){
next=head.next;
return head;
}
ListNode l= reverseToN(head.next,n-1);
head.next.next=head;
head.next=next;
return l;
}
}