持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
一、题目
struct ListNode {
int val;
ListNode *next = nullptr;
inline ListNode(int x, ListNode* next = nullptr) : val(x), next(next) { }
};
ListNode* reverseList(ListNode* pHead) {
ListNode* result = nullptr;
//------
return result;
}
int main()
{
ListNode root(1);
ListNode p2(2);
ListNode p3(3);
root.next = &p2;
p2.next = &p3;
p3.next = nullptr;
ListNode* pHead = &root;
ListNode* cur = pHead;
while(cur){
cout << cur->val << endl;
cur = cur->next;
}
cur = reverseList(pHead);
while(cur){
cout << cur->val << endl;
cur = cur->next;
}
return 0;
}
二、分析
ListNode *next = nullptr;
难点一: 该链表是单向链表
难点二: 要返回新的表头
根据题意,我们需要将链表反转,说到链表,很容易想到只需要获取下一个节点,让下一个节点的next指针指向自己,再让下一个节点的下一个节点的next指针指向下一个节点,循环下去就能达到目的。
但是这样就造成了修改了p2的next,就无法获取p3的指针了
将算法修改一下,先获取p3,再去修改p2,就能达到目的了。
三、模拟
- 获取当前节点
ListNode* cur = pHead;
- 获取下一个节点
ListNode* next = cur->next;
- 修改当前节点
cur->next = cur->(之前指向cur的节点);
- 迭代
cur = next;
如此循环修改便能完成,模拟过程中只有一个未知量,就是指向当前节点的前节点,设为pre,头指针是第一个节点,在转变后,就是最后一个节点,最后一个节点的next应该等于NULL,然后在循环迭代过程中,pre一直等于修改的当前节点。
四、实现
ListNode* reverseList(ListNode* pHead) {
ListNode* result = nullptr;
ListNode* cur = pHead;
ListNode* pre = nullptr;
while(cur){
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
result = pre;
return result;
}
因为循环的原因,cur指向NULL才结束循环,而真正的头结点就是NULL之前的节点,也就是pre
五、结言
这道题有两个思维误区:
1. 倒转需要先修改前面的节点
2. 当前结点倒转后就是之前next节点的next指针