1. LC92-反转链表2
题目链接
采用头插法。这样只用一次遍历就可以。
定义两个指针,一个指针pre指向left的前一个节点,一个指针cur。cur的next插到最前面,即pre的next。
代码
class Solution {
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
ListNode cur = head;
for (int i=1; i<left; i++){
pre = pre.next;
cur = cur.next;
}
for (int i=left; i<right; i++){
ListNode next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummy.next;
}
}
易错点:
- next.next = pre.next,而不是next.next = cur。因为cur一直指向的是反转前的第一个节点,反转后的最后一个节点,如果头插法next插到最前面的话,next的下一个节点一定是原本的pre.next。
- 遍历数量,当做i指向的就是cur的位置。
- 最开始一定要定义dummy的下一个节点是cur,因为反转的遍历过程中,有用到pre.next
2. LC25. K个一组翻转链表
思路:
求出链表长度,求出分组个数。
对于每一组,用上题思路进行反转。pre为上一组的最后一个节点,cur为这一组反转后的最后一个节点。所以每一组反转后,都调整 pre = cur
, cur = cur.next
。
易错:
- 又忘了定义pre.next = cur;
- 在求完链表长度后,cur要回到head的位置。
代码:
class Solution {
public ListNode reverseKGroup(ListNode head, int k) {
ListNode dummy = new ListNode(-1);
ListNode pre = dummy;
ListNode cur = head;
pre.next = cur;
int length = 0;
while(cur != null){
length++;
cur = cur.next;
}
int group = length / k;
cur = head;
while (group > 0){
for (int i=1; i<k; i++){
ListNode next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
group--;
pre = cur;
cur = cur.next;
}
return dummy.next;
}
}