题目描述
请将链表中第 $n$ 个节点和第 $m$ 个节点之间的部分翻转。
链表最多只能遍历一遍。
注意:$1 \le m \le n \le$ 链表长度。
样例
输入:1->2->3->4->5->NULL, m = 2, n = 4
输出:1->4->3->2->5->NULL
算法
(模拟) $O(n)$
假设初始链表如下所示:
第一步,我们先将 $m$ 到 $n$ 之间的指针翻转(不包含第 $m$ 个节点),如下所示:
第二步我们将 $m$ 的指针指向 $c$,将 $a$ 的指针指向 $n$,如下所示:
此时我们就完成了 $m$ 到 $n$ 之间的翻转!
时间复杂度分析:整个链表只遍历了一遍,所以时间复杂度是 $O(n)$。
C++ 代码
/**
* 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) {
if (m == n) return head;
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *p = dummy;
for (int i = 0; i < m - 1; i ++ )
p = p->next;
ListNode *a = p, *b = a->next, *c = b->next;
for (int i = m + 1; i <= n; i ++ )
{
ListNode *d = c->next;
c->next = b;
b = c;
c = d;
}
a->next->next = c;
a->next = b;
return dummy->next;
}
};
y总什么时候要初始化一个dummy把dummy的next指向head,什么时候直接指针指向head就好了?
因为head可能参与被翻转,所以需要一个独立它之外的头部指针代表头部
看完之后,发现自己写得复杂了//
发现y总更新了一下这道题的解法,请问y总为什么最后a->next->next = c; a->next = b; 的顺序不能反过来?都是将箭头重新指了一下方向,为什么就会报错?
因为如果反了,a->next就会先指向b,那么a->next->next就不是指向c了。这顺序就是为了保证a->next不会先变化
It is a best solution found that very popular and helpful:
https://www.youtube.com/watch?v=Oo50xnRvXOs&ab_channel=EricProgramming
为什么返回函数内部定义的局部变量指针还不会出错??有点懵欸
dummy是new出来的,开辟的内存是在堆上。不是栈里的临时变量。