题目描述:给定单链表的头节点 head
,请反转链表,并返回反转后的链表的头节点。
示例 1: 输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
示例 2: 输入:head = [1,2] 输出:[2,1]
class Solution {
public:
ListNode* reverseList(ListNode* head)
{
vector<int> reList; //存放链表节点值的数组
ListNode *res , *p = head;
while(p)
{
//依次将链表节点顺序插入数组中
reList.push_back(p->val);
p = p->next;
}
// reverse(reList.begin(),reList.end());
// res = head;
// for(int i=0;i<reList.size();i++)
// {
// res->val = reList[i];
// res = res->next;
// }
res = head;
for(int i = reList.size()-1; i >= 0; i--)
{
res->val = reList[i];
res = res->next;
}
return head;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head)
{
//利用栈存储链表节点值
stack<int> st;
while(head != nullptr)
{
st.push(head->val);
head = head->next;
}
ListNode* dummy = new ListNode(-1);
ListNode* p = dummy;
while (!st.empty())
{
p->next = new ListNode(st.top());
if (!st.empty())
st.pop();
p = p->next;
}
return dummy->next;
}
};
方法一:迭代
class Solution {
public:
ListNode* reverseList(ListNode* head)
{
ListNode* res = nullptr;
while (head != nullptr){
ListNode* newHead = new ListNode(head->val);
newHead->next = res;
res = newHead;
head = head->next;
}
return res;
}
};
对于本题来说,采用迭代法去做,一般会都会设置三个指针。
pre:指向当前节点的前一节点,用于反转链表;
cur:指向当前节点,用于遍历整个链表;
next:指向当前节点的后(下)一节点,用于在反转前,保留 cur 的下一节点,防止反转时,链表断开,无法找到 cur 后面的节点。
class Solution {
public:
ListNode* reverseList(ListNode* head)
{
if(head == NULL || head->next == NULL)
{
return head;
}
ListNode *pre = nullptr,*cur = head;
while(cur != nullptr)
{
ListNode *next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
};
方法二:递归
考虑使用递归法遍历链表,当越过尾节点后终止递归,在回溯时修改各节点的 next 引用指向。
recur(cur, pre) 递归函数:
1、终止条件:当 cur 为空,则返回尾节点 pre (即反转链表的头节点);
2、递归后继节点,记录返回值(即反转链表的头节点)为 res ;
3、修改当前节点 cur 引用指向前驱节点 pre ;
4、返回反转链表的头节点 res ;
reverseList(head) 函数:
调用并返回 recur(head, null) 。传入 null 是因为反转链表后, head 节点指向 null ;
class Solution {
public:
ListNode* reverseList(ListNode* head)
{
return recur(head, nullptr); // 调用递归并返回
}
private:
ListNode* recur(ListNode* cur, ListNode* pre)
{
if (cur == nullptr) return pre; // 终止条件
ListNode* res = recur(cur->next, cur); // 递归后继节点
cur->next = pre; // 修改节点引用指向
return res; // 返回反转链表的头节点
}
};