LeetCode206. 反转链表【双指针和递归】

LeetCode206.反转链表

1.题目

在这里插入图片描述

2.思路

1.我最初的设想是把最后一个节点依次前移,后来发现有两个困难。一是单向链表没办法访问已知结点的前驱结点,犯了一些错误。比如:
(1) LinkNode*q; q->next = p; //q根本没指向p的前驱
(2)LinkNode *q = dummyHead; q->next = p; //这样会变成dummyHead的next变为p 链表错排了!
二就是如果需要访问前驱节点,每次都需要遍历,时间复杂度太高。综上,我放弃了这个想法。
2.双指针应用。设定一前一后两个结点顺次后移。使后面的节点的指针指向它前面的结点。
3.递归。
下面分开实现一下。

3.代码实现

(1)双指针应用

双指针的基本思路:
没有哨兵结点版

1.我最开始的思路是统计链表长度,特判长度为0/1的情况,最后使用双指针。这样略复杂
2.记得使用tmp结点保存后指针后面的结点,要不就丢了
主体思路就是上图:(1)保存结点(2)指针反转(3)指针后移

先贴我自己最初始的代码,很复杂,有很多多余的步骤…

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
	ListNode* dummyHead = new ListNode(1);//哨头结点 考虑头结点为空 
	if(head!= NULL) dummyHead->next = head; 
	ListNode* p = dummyHead;
	int size = 0;//初始化!
	while(p->next != NULL)
	{
		p = p->next;
		size++;//链表长度 
	}
	//特判空链表和长度为1的情况
	if(size == 0) return nullptr;
	else if(size == 1) return head;
	else{
		ListNode *m = dummyHead->next;
		ListNode *n = dummyHead->next->next;
        ListNode *tmp;
		while(n != NULL)
		{//保存节点
			tmp = n->next;
		//反转
            n->next = m;
            m = n;
        //后移
            n = tmp;
		}
        dummyHead->next->next = nullptr;//这句必须有
        delete dummyHead;
		return m;
		}
	}
};

和大佬的代码对比了一下有两个最大的缺点:

1.没有必要使用哨兵结点,太多余,而且容易丢掉dummyHead->next->next = nullptr;这一步。
2.最近养成了特判的意识,会对空链表和节点为1的链表进行思考了,很开心。但是不一定需要特判,可以更精简!

精简之后的代码:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
	ListNode* tmp;
	ListNode* m = NULL;
	ListNode* n = head;
	while(n != NULL)
	{
	//保存节点
		tmp = n->next;
	//反转
		n->next = m;
	//后移
		m = n;
		n = tmp;
	}//不用对头结点进行特判了,第一步就置为NULL了
	return m;
	}
};
(2)递归方法

和双指针是一样的思路

ListNode* reverse(ListNode*m,ListNode* n){
	if(n == NULL) return m;//递归出口 
	//存点 
	ListNode* tmp = n->next;
	//交换
	n->next = m;
	//后移 这里我卡了一会儿 但其实和双指针思路一样
	//m = n;
	//n = tmp; 
	return reverse(n,tmp);
}

ListNode* reverseList(ListNode* head) {
	//就是双指针的初始化 
	//ListNode* m = NULL; ListNode* n = head;
	return reverse(NULL,head);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值