各位题友大家好! 今天是 @负雪明烛 坚持日更的第 53 天。今天力扣上的每日一题是「92. 反转链表 II」。
解题思路
这个题明显是「206. 反转链表」的进阶版,所以请在做出本题前,保证自己能做出 206 题。
反转链表问题的难点在于指针的指向修改,其实只要理清楚思路,一般不会出错的。链表题目建议自己在纸上画一画。
今天的翻转指定区间的链表,需要以下指针:
1. 指向 left
左边元素的指针 pre
,它表示未翻转的链表,需要把当前要翻转的链表结点放到 pre
之后。
2. cur
指向当前要翻转的链表结点。
nxt
指向cur.next
,表示下一个要被翻转的链表结点。tail
指向已经翻转的链表的结尾,用它来把已翻转的链表和剩余链表进行拼接。
具体的翻转过程如下面的动图所示,指针虽然多,但是每个指针的移动都有自己的规则的,所以逐个指针去维护,应该不难。
代码
代码中的哑节点 dummy:
创建 哑节点 作为 链表 的新开头,返回结果是这个节点的下一个位置。目的是:如果要翻转的区间包含了原始链表的第一个位置,那么使用 dummy 就可以维护整个翻转的过程更加通用。
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution(object):
def reverseBetween(self, head, left, right):
count = 1
dummy = ListNode(0)
dummy.next = head
pre = dummy
while pre.next and count < left:
pre = pre.next
count += 1
cur = pre.next
tail = cur
while cur and count <= right:
nxt = cur.next
cur.next = pre.next
pre.next = cur
tail.next = nxt
cur = nxt
count += 1
return dummy.next
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
int pos = 1;
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* pre = dummy;
ListNode* cur = head;
while (cur && pos < m) {
pre = pre->next;
cur = cur->next;
pos ++;
}
ListNode* tailNode = cur;
while (cur && pos <= n) {
ListNode* nxt = cur->next;
cur->next = pre->next;
pre->next = cur;
tailNode->next = nxt;
cur = nxt;
pos ++;
}
return dummy->next;
}
};
- 时间复杂度:$O(N)$
- 空间复杂度:$O(1)$
刷题心得
- 这个题是我们春节期间的模拟面试挑选的题目。
- 如果输入的数据 [m,n] 不一定满足 1 ≤ m ≤ n ≤ 链表长度。那么该怎么做呢?
OK,以上就是 @负雪明烛 写的今天题解的全部内容了,如果你觉得有帮助的话,求赞、求关注、求收藏。如果有疑问的话,请在下面评论,我会及时解答。
关注我,你将不会错过我的精彩动画题解、面试题分享、组队刷题活动,进入主页 @负雪明烛 右侧有刷题组织,从此刷题不再孤单。
祝大家牛年大吉!AC 多多,Offer 多多!我们明天再见!