各位题友大家好! 今天是 @负雪明烛 坚持日更的第 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 = nextclass Solution(object):def reverseBetween(self, head, left, right):count = 1dummy = ListNode(0)dummy.next = headpre = dummywhile pre.next and count < left:pre = pre.nextcount += 1cur = pre.nexttail = curwhile cur and count <= right:nxt = cur.nextcur.next = pre.nextpre.next = curtail.next = nxtcur = nxtcount += 1return 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 多多!我们明天再见!
