一边扫描,使用伪头节点,好理解!
思路
涉及到链表,多想想伪头节点来简化特殊判断。
- 开局先扫描,找到left的前面一个节点t,这里也提前给原链表加个dummyHead伪头节点,防止left从1开始翻转。
- 同时记录一下left位置的节点(tail),因为它翻转之后是要连接上后面那段不需要反转的链表的。
- 然后就开始从left开始到right把遍历到的每一个节点使用头插法插入到dummy链表中。这里需要注意使用temp提前拿到下一个节点,否则会被改掉。
- 最后把翻转的链表拼起来就ok了。
代码
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
int cur = 0;
ListNode dummy = new ListNode(), dummyHead = new ListNode(-1, head), p = dummyHead;
while(p != null && cur < left - 1){
p = p.next;
cur++;
}
ListNode t = p, tail = p.next;
ListNode temp = p.next;
while(cur <= right){
temp = p.next;
p.next = dummy.next;
dummy.next = p;
cur++;
p = temp;
}
t.next = dummy.next;
tail.next = temp;
return dummyHead.next;
}
}
复杂度分析
时间复杂度
只遍历一遍 O ( n ) O(n) O(n)
空间复杂度
常数级额外空间 O ( 1 ) O(1) O(1)