学习日期:2025年1月18日22:23:12
学习内容:反转链表 (常考
)
学习时长:1h30min
+20min
练习题目
题目描述
题意:反转一个单链表。
示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
解题思路
✅😃画图分析
解法1:双指针
指针cur
,指针pre
注意:
- 指针
cur
,指针pre
的初始化 - 循环遍历的终止条件——根据
cur
指针的移动来确定:✅cur
指向null时结束 - 保存
cur->next
的临时指针tmp
- 指针的移动顺序:先移动
pre
,后移动cur
😏按照注意事项,写的很快,超级简单!没报错,一次过。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
//解法1:双指针
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* cur=head;
ListNode* pre=nullptr; //指针初始化
ListNode* tmp;//保存cur的下一个节点
while(cur){
tmp=cur->next;//保存cur->next,便于移动cur指针
cur->next=pre;//反转链表
pre=cur;//双指针向后移动
cur=tmp;
}
return pre;//返回新的头指针
}
};
解法2:递归
按照解法1:双指针的思路写递归解法
- 初始条件
- 递归中止条件
- 反转操作
- 递归循环
bug记录
报错原因:函数定义未写对(#`O′)
报错原因:line21 应为 return my_Reverse(cur,tmp);
报错原因:未进行翻转操作cur=pre->next;
//解法2:递归
class Solution {
public:
//定义递归函数
ListNode* my_Reverse(ListNode*pre,ListNode*cur){
ListNode* tmp;
//递归终止条件
if(cur==NULL) return pre;
tmp=cur->next;
cur->next=pre;//反转操作
//进入下一层递归
return my_Reverse(cur,tmp);
//将双指针的移动写进递归体,也就是"把循环写成递归"
// pre = cur;
// cur = temp;
}
ListNode* reverseList(ListNode* head) {
return my_Reverse(NULL,head);
//pre与cur指针的初始化,参考双指针解法
}
};
//递归2:从后往前反转
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// 边缘条件判断
if(head == NULL) return NULL;
if (head->next == NULL) return head;
// 递归调用,翻转第二个节点开始往后的链表
ListNode *last = reverseList(head->next);
// 翻转头节点与第二个节点的指向
head->next->next = head;
// 此时的 head 节点为尾节点,next 需要指向 NULL
head->next = NULL;
return last;
}
};
😅看不懂(#`O′),这个思路和双指针思路不同,我也不知道递归代替的循环体是什么...
学习总结
- “反转链表”是高频面试题
- 递归写法难理解,可建立在双指针解法的思路上去理解
- 递归函数的写法
不熟
- 从后往前的递归思路