剑指offer:反转链表

题目:

输入一个链表,反转链表后,输出新链表的表头。

思路:

方法1:利用辅助空间,不推荐

利用栈的辅助空间,先将链表元素入栈,再将元素出栈; 利用数组的辅助空间,先遍历链表将其放入一个数组,然后把数组从后往前形成新链表。

方法2:

不需要辅助空间,每一次反转需要维护三个指针,当前节点pNode,前一节点pPre(因为当前节点反转要指向前一节点),下一节点pNext(在改变当前节点指向之前,必须先保存下一节点,否则链表会断开),依次反转,直到遍历完(pNode=NULL,全部节点完成反转)。要注意几点:

1)第一个节点反转之后变为尾节点,应该指向NULL,因此pPre初始化为NULL;

2)最后返回的头指针是最后一个节点,因此当循环结束,pNode=NULL,pPre指向的是最后一个节点,记得要把pPre设为新的链表头结点;

3)特殊情况的处理:空链表,只有一个节点的链表,这种情况直接返回头指针。

方法3:用递归的方法实现

以1->2->3->4为例,先利用递归走到链表末端,首先1节点传入头指针参数,进入else语句,一直递归到最后一个4节点,p->next为空,进入if语句返回4作为newHead;然后pHead变为节点3,上一级返回之后的操作是将当前结点的下下节点指向当前节点(即4指向3),然后将当前节点指向空,这样剩下就是处理1->2->3新链表,可以递归操作。

代码:

参考下面的在线测试代码

在线测试OJ:

https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=13&tqId=11168&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

AC代码:

非递归

/*
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};*/
class Solution {
public:
   ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL || pHead->next == NULL)//特殊情况:空链表,只有一个节点的链表
            return pHead;
        ListNode* pNode = pHead;//当前节点
        ListNode* pNext;//下一节点
        ListNode* pPre=NULL;//前一节点
        ListNode* pNewHead;//新的链表头结点
        while(pNode)
        {
            pNext = pNode->next;
            pNode->next = pPre;
            pPre = pNode;
            pNode = pNext;
        }
        pNewHead=pPre;
        return pNewHead;
    }
};

递归

class Solution {
public:
    ListNode* ReverseList(ListNode* pHead) {
        if(pHead == NULL || pHead->next == NULL)
            return pHead;
        else
        {
            ListNode* newHead = ReverseList(pHead->next);
            pHead->next->next=pHead;
            pHead->next = NULL;
            return newHead;
        }
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值