反转链表
一、题目描述
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
作者:Krahets 链接:https://leetcode-cn.com/leetbook/read/illustration-of-algorithm/9pdjbm/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
二、解题思路及代码实现
1、解题思路
列表和数组不同,列表并不是连续的内存空间,其包含指针域和数据域,要想反转列表,只需要操作指针域即可,遍历链表,把后一个节点指向前一个节点,直到结束为止。只遍历一次链表,且无拷贝节点数据域,操作效率和内存消耗应该是比较少的。最初想到的一个办法是把数据域保存到栈容器,再把栈容器数据取出来放到链表中,达到反转目的,测试的时候,发现这样执行需要遍历链表两次,且消耗额外容器,其执行效率和内存使用效率都比较低。
2、C++代码实现
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) return head;
ListNode* left = head;
ListNode* center = head->next;
if (center->next == NULL) {
center->next = left;
left->next = NULL;
return center;
} else {
left->next = NULL;
ListNode* right = center->next;
while (right != NULL && right->next != NULL) {
center->next = left;
left = center;
center = right;
right = right->next;
}
center->next = left;
right->next = center;
return right;
}
}
};
三、提交结果
总结
链表直接操作指针效率是最高的,但要小心指针的应用,避免越界操作,否则极易出现崩溃状况。如下代码是我第一版的解决方案,效率不高,使用了栈容器。虽然效果不怎么样,但学习一下栈的使用,也是不错的。
class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* tmp = head;
stack<int> stk;
while (tmp != NULL) {
stk.push(tmp->val);
tmp = tmp->next;
}
tmp = head;
while (tmp != NULL) {
tmp->val = stk.top();
stk.pop();
tmp = tmp->next;
}
return head;
}
};
|