【LeetCode 206. 反转链表】——链表,迭代法,递归法

206. 反转链表:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。

示例 1:

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]

示例 2:

输入:head = [1,2]
输出:[2,1]

示例 3:

输入:head = []
输出:[]

提示:

  • 链表中节点的数目范围是 [0, 5000]
  • -5000 <= Node.val <= 5000

**进阶:**链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?

思考:

链表的翻转也属于是链表的一种基本操作。而具体的实现方式,其实就是改变链表中每个结点指向的next结点。所以我们可以用迭代法和递归法这两种方法来实现,其本质其实是一样的。

迭代法:

定义三种指针preNode、currentNode、next进行迭代操作。直至最后一位。

//Definition for singly-linked list.
 struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
 };
 
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* preNode = nullptr; //前向前结点的指针
        ListNode* currentNode = head; //当前指针

        while (currentNode) //进行迭代操作
        {
            ListNode* next = currentNode->next;//指向后结点的指针
            currentNode->next = preNode; //原本指向后面,现在指向前面
            preNode = currentNode; //移动前指针
            currentNode = next; //移动当前指针至下一位
        }
        return preNode;
    }
};

递归法:

在迭代法的基础上,简化算法,运用递归的思想,而不是使用循环。在一开始时,要对链表进行讨论,是否为空链表,此时返回空。而递归的结束条件则为,head->next为空,即已经遍历到了最后一位。

//Definition for singly-linked list.
 struct ListNode {
     int val;
     ListNode *next;
     ListNode() : val(0), next(nullptr) {}
     ListNode(int x) : val(x), next(nullptr) {}
     ListNode(int x, ListNode *next) : val(x), next(next) {}
 };
 
class Solution {
public:
    ListNode* reverseList2(ListNode* head) {
        // 边缘条件判断
        if (head == NULL) return NULL;
        if (head->next == NULL) return head;

        // 递归调用,翻转第二个节点开始往后的链表
        ListNode* last = reverseList(head->next);
        // 翻转头节点与第二个节点的指向
        head->next->next = head;
        // 此时的 head 节点为尾节点,next 需要指向 NULL
        head->next = NULL;
        return last;
    }
};

其他:

值得一提的是,对于我们之前提到的含有虚拟头结点的链表,若要进行翻转,我们要将那个虚拟头结点始终置于头部,若使用上述方法,原本的虚拟头指针会变成最后一位,成为虚拟尾指针。

所以我们可以使用下述方法:

//链表逆置
List Inverse(List L)
{
	List p, q;
	p = L->Next;     //p指针指向第一个结点
	L->Next = NULL;  //头结点指向NULL

	while (p != NULL) {
		q = p;
		p = p->Next;
		q->Next = L->Next;
		L->Next = q;
	}
	return L;
}

往期回顾:
LeetCode 707.设计链表
LeetCode 203.移除链表元素
LeetCode54. 螺旋矩阵
LeetCode59.螺旋矩阵II
LeetCode977.有序数组的平方
LeetCode844.比较含退格的字符串
LeetCode283.移动零
LeetCode27.移除元素
LeetCode26.删除有序数组中的重复项
LeetCode209.长度最小的子数组
LeetCode904. 水果成篮
LeetCode242.有效的字母异位词
LeetCode76.最小覆盖子串

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值