【LeetCode 刷题笔记】 01 链表倒序输出的几种常见思路
【LeetCode 刷题笔记】 01 链表倒序输出的几种常见思路
鸽了好久的第一篇博客终于开始写了。没啥太多的开场白,直接上干货吧。
这篇博客主要聚焦于博主最近在LeetCode上面刷的一些简单的链表题目,主要介绍关于链表倒序输出的一些思路和常见方法。
一、链表倒序输出的常见思路
1. 迭代
迭代法是最朴素的想法。其通过在原链表的基础上逐步改变每个节点的next指针的指向从而得到逆序链表。
优点:空间消耗较小(只需要在原链表的基础上改动)。
缺点:不断改动指针有可能绕晕初学者。
2. 栈
栈的特点是先进后出(FILO)。我们可以将链表倒序的过程想象成将链表的每个结点一个个压入栈中,再一个个从栈中弹出再链接的过程。
优点:思路简单清晰,操作易实现。
缺点:对空间消耗较大,空间复杂度为O(N)。
3. 递归
递归算法也可以解决链表的逆序问题。
优点:程序代码简洁,可以降低问题的复杂度。
缺点:设计思路较难,需要经过足够的练习才能有一定的思路灵感。
二、题目实战
此部分主要以一题多解的方式呈现。每一道题都主要讲解其中一种或两种解法。
1. 【LeetCode 24】 两两交换链表中的节点
递归法:
ListNode* swapPairs(ListNode* head)
{
if (head == nullptr || head->next == nullptr)
return head;
ListNode* temp = head->next;
head->next = swapPairs(head->next->next);
temp->next = head;
return temp;
}
个人心得:当看到这题的时候我想到可以用递归的方法写,就直接写了。可以看出递归只需要思考怎么交换两个节点,代码是非常简洁的。
2. 【LeetCode 25】 K 个一组翻转链表
栈法:
ListNode* reverseKGroup(ListNode* head, int k)
{
bool smallerthanK = 0;
ListNode* p, * q;
p = q = head;
for (int i = 0; i < k; i++, q = q->next)
{
if (q == nullptr)
{
smallerthanK = 1;
break;
}
}
if (smallerthanK == 1)
return head;
stack<ListNode*> Lstack;
for (int i = 0; i < k; i++) //入栈
{
Lstack.push(p);
p = p->next;
}
ListNode* subhead = Lstack.top(), *u = subhead;
Lstack.pop();
for (int i = 1; i < k; i++) //出栈
{
u = u->next = Lstack.top();
Lstack.pop();
}
u->next = reverseKGroup(q, k);
return subhead;
}
个人心得:这题其实可以像上一题一样用递归法,但使用栈是最方便的。
3. 【LeetCode 92】 反转链表 II
迭代法:
ListNode* reverseBetween(ListNode* head, int m, int n)
{
if (m == n)
return head;
ListNode* dummy = new ListNode(-1, head), * p = dummy, * q = dummy;
for (int i = 0; i < m - 1; i++)
q = q->next;
p = q;
p = p->next;
for (int j = m; j < n; j++) //这个循环是精髓
{
ListNode* t = p->next->next;
p->next->next = q->next;
q->next = p->next;
p->next = t;
}
return dummy->next;
}
个人心得:这题也可以用栈法,但是栈占用空间会比较大。其实偶尔写一下迭代法既可以强化自己对链表的理解,又可以挑战自己的能力,何乐而不为呢?
三、小结
以上是个人对于链表中倒序输出的常用方法的总结。由于本人水平有限,出现错漏也在所难免。欢迎批评指正。

浙公网安备 33010602011771号