反转一个链表
解题思路:
1.定义当前遍历节点cur,cur的前驱节点pre,cur的后继的节点next
2.初始化cur=head,pre=null,next=cur.next
3.遍历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) {
ListNode pre=null;
ListNode cur=head;
while(cur!=null){
ListNode next=cur.next;
cur.next=pre;
pre=cur;
cur=next;
}
return cur;
}
}
递归
解题思路:
1-> 2->3->4->5
reverseList: head=1
reverseList: head=2
reverseList: head=3
reverseList:head=4
reverseList:head=5
终止返回
cur = 5
4.next.next->4,即5->4
cur=5
3.next.next->3,即4->3
cur = 5
2.next.next->2,即3->2
l
cur = 5
1.next.next->1,即2->1
1.next=null
最后返回cur
reverseList(head.next) 此时最后一层结束递归的条件是head.next == null , head 等于 5 , 那么它的上一层就是 reverseList(4.next) , head 等于4 , 因此后面head.next.next = head 相当于 4的后面的后面指向4 , 那就是 4<-5
然后 head.next = null , 最后renturn p , 倒数第二层往上返回了 null <- 4 <-5 。
最顶层通过递归条件 head == null 整体结束
ListNode last = reverse(head.next);
reverse(head.next) 执行完成后,整个链表就成了这样
head.next.next = head;
head.next = null;
return last;
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) return head;
ListNode p = reverseList(head.next);
head.next.next = head;//逆置
head.next = null;//断开原来后面的节点
return p;
}
反转链表前 N 个节点
执行 reverseN(head, 3):
1、base case 变为 n == 1,反转一个元素,就是它本身,同时要记录后驱节点。
2、刚才我们直接把 head.next 设置为 null,因为整个链表反转后原来的 head 变成了整个链表的最后一个节点。但现在 head 节点在递归反转之后不一定是最后一个节点了,所以要记录后驱 successor(第 n + 1 个节点),反转之后将 head 连接上。
ListNode successor = null; // 后驱节点
// 反转以 head 为起点的 n 个节点,返回新的头结点
ListNode reverseN(ListNode head, int n) {
if (n == 1) {
// 记录第 n + 1 个节点
successor = head.next;
return head;
}
// 以 head.next 为起点,需要反转前 n - 1 个节点,last是反转后的头结点
ListNode last = reverseN(head.next, n - 1);
head.next.next = head;
// 让反转之后的 head 节点和后面的节点连起来
head.next = successor;
return last;
}
将一个链表m位置到n位置之间的区间反转,要求使用原地算法,并且在一次扫描之内完成反转。
例如:
给出的链表为1->2->3->4->5->NULL, m = 2 ,n = 4,
返回1->4->3->2->5->NULL.
注意:
给出的m,n满足以下条件:
1 ≤ m ≤ n ≤ 链表长度
import java.util.*;
/*
* public class ListNode {
* int val;
* ListNode next = null;
* }
*/
public class Solution {
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
public ListNode reverseBetween (ListNode head, int m, int n) {
if(m==1){
return reverseN(head,n);
}
// 前进到反转的起点触发 base case
head.next=reverseBetween(head.next,m-1,n-1);
return head;
}
ListNode successtor=null;
ListNode reverseN(ListNode head,int n){
//如果只有一个节点,找到了后继节点
if(n==1){
successtor=head.next;
return head;
}
ListNode last=reverseN(head.next,n-1);//找到反转后的头结点
head.next.next=head;
head.next=successtor;//将head连接到后继节点,俩接起来
return last;
}
}