24 反转链表
题目
定义一个函数,输入一个链表的头结点,反转该链表并输出反转后链表的头结点。
C++ 题解
方法一
循环翻转链表,每次循环翻转一个结点。判断node是否是最后一个结点,如果是最后一个节点,则reverseHead指向node(确定翻转链表表头节点),然后node指向left(翻转链表),退出循环;如果不是最后一个节点,则node指向left(翻转链表),移动left和node指针。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead)
{
if(pHead == nullptr)
return nullptr;
// 定义当前的节点,初始化为pHead
ListNode* pCurr = pHead;
// 定义一个前驱节点,初始化为nullptr
ListNode* pPrev = nullptr;
// 遍历当前的链表
while(pCurr)
{
// 记下当前节点的后继节点
ListNode* pNext = pCurr->next;
// 反转两个节点:即将后面的节点直接指向前面的节点
// 对于原链表中的第一个结点正好将其后继节点指向nullptr,因为反转之后它是尾节点
pCurr->next = pPrev;
// 反转后链表的前驱节点记作当前节点
pPrev = pCurr;
// 当前节点前进
pCurr = pNext;
}
return pPrev;
}
};
方法二
采用递归实现:
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* ReverseList(ListNode* pHead)
{
//如果链表为空直接返回,pHead->next是递归基
if(!pHead || !pHead->next)
return pHead;
//先反转后面的链表,走到链表的末端结点
ListNode* res = ReverseList(pHead->next);
//再将当前节点设置为后面节点的后续节点
pHead->next->next = pHead;
// 断开链表连接,否则链表将成为环
pHead->next = nullptr;
// 新链表头永远指向的是原链表的链尾
return res;
}
};
注意:
- 递归的方法其实是非常巧的,它利用递归走到链表的末端,然后再更新每一个node的next 值 ,实现链表的反转。
python 题解
基于非递归的解法
# -*- coding:utf-8 -*-
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
# 返回ListNode
def ReverseList(self, pHead):
# write code here
pCurrent = pHead
pPrev = None
while pCurrent != None:
pNext = pCurrent.next
pCurrent.next = pPrev
pPrev = pCurrent
pCurrent = pNext
return pPrev