#LeetCode每日一题【链表专题】
- 反转链表 II
https://leetcode-cn.com/problems/reverse-linked-list-ii/ - 分析
在反转链表的基础上进行的扩展,将指定位置上的链表进行反转
思路:遍历的时候,记录长度,当达到left时,开始反转;大于right之后直接结束;
指定区间反转成功之后,在拼接上left之前的以及right之后的即可;
所以一轮遍历的时候,记录下left的上一位、left位置以及right的下一位 - 实现
public ListNode reverseBetween(ListNode head, int left, int right) {
int length = 0;
// 引入哑节点的好处就是:不用将头节点进行特殊处理
ListNode dummy = new ListNode(0, head);
ListNode prev = null, next, startPrev = null, start = null, node = dummy;
while (node != null && length <= right) {
next = node.next;
// 标记开始反转的上一个位置:用于最后的拼接
if (length == left - 1) {
node.next = null;
startPrev = node;
}
// 标记开始反转的位置:用于最后的拼接
if (length == left) {
start = node;
}
// 开始反转,反转区间
if (length >= left) {
node.next = prev;
prev = node;
}
node = next;
length++;
}
// 结束反转之后处理
// 拼接上反转的
startPrev.next = prev;
// 拼接上剩余的
start.next = node;
return dummy.next;
}
LeetCode耗时:0ms
· 总结
- 链表引入哑节点的好处就是:不需要将头节点进行特殊处理,头节点也可以看成正常的节点:是某节点的下一个
- 链表问题需要理解:除了自己new出来的ListNode,其他你定义的都是引用,其实对象都只有一份
多个引用操作的对象是一样的,其产生的结果是相同的
这也是为什么常常都是定义一份新的引用出来操作,操作的同时如果涉及指向改变,那同时也影响原引用