一、全部反转
-
题目
-
分析
- 我们要让当前节点的next指向上一节点[反转]
- 反转之前应当保存next的信息,使可以向下遍历
- 当前节点无法直接获取上一节点的引用,需要在上一次循环时存储
- 重点:当前节点无法拿到上节点的引用,需要用中间变量保存
- 图解
- 关键代码
/**
* 返回反转链表
*/
public ListNode reverseOne(ListNode head) {
//前节点
ListNode pre = null;
//后节点
ListNode next;
while (head != null) {
//保存当前后置节点引用
next = head.next;
//反转指向前一节点
head.next = pre;
//保存当前节点作为下一节点的前置节点
pre = head;
//节点后移
head = next;
}
return pre;
}
二、局部反转
- 题目
- 分析
- 取出临节点插入到首届点
- 连接首节点到临节点的下一节点
- 重点:引用概念不清会导致栈溢出
- 图解
- 关键代码
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) {
//注意点 1.链表的结果输出 2.单节点判断 3.双节点处理
if (head == null || head.next == null) return head;
//反转前置节点
ListNode pre = new ListNode(0);
//head引用变化会导致打印不完整
pre.next = head;
//m,n范围内反转
int headIndex = 0;
//使用缓存引用 保证打印正常
ListNode headTemp=head;
ListNode preTemp=pre;
//右临节点
ListNode next_r = null;
for (int i = 1; i < m ; i++) {
preTemp = headTemp;
headTemp = headTemp.next;
}
while (headIndex < n - m) {
headIndex++;
//③ 临节点
next_r = headTemp.next;
//⑤ 向下移位 连接临节点的下一节点
headTemp.next = next_r.next;
//④ 临节点指向首节点
next_r.next = preTemp.next;
//② 前置节点指向临节点
preTemp.next = next_r;
}
return pre.next;
}
}