前言
LeetCode链表题汇总,记录解题思路,C/C++语言实现。
LeetCode链表题
判断链表是否有环 :https://leetcode-cn.com/problems/linked-list-cycle/
输出环形链表的入环点:https://leetcode-cn.com/problems/linked-list-cycle-ii/
输出链表中倒数第k个节点:https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/
解题思路
判断链表是否有环
思路:快慢指针法。 慢指针每前进一步,快指针就前进两步。如果快慢指针能相遇,证明有环,反之无环。
1 | /** |
输出环形链表的入环点
以下给出两种思路:
方法一: 遍历一次链表,将遍历到的节点存储到哈希表,如果节点已经在哈希表中,说明有环,输出入环点。
复杂度分析: 时间复杂度O(N), 空间复杂度O(N)
1 | ListNode *detectCycle(ListNode *head) { |
方法二: 快慢指针法。创建fast, slow两个指针指向链表头,令fast前进速度为slow的两倍。当快慢指针相遇时,再创建一个指针p指向链表头, 让p和slow等速前进,p和slow必定会相遇,且相遇点即为入环点。
数学证明参考:LeetCode官方题解
复杂度分析: 时间复杂度O(N), 空间复杂度O(1)
1 | ListNode *detectCycle(ListNode *head) { |
输出链表中倒数第k个节点
以下给出两种思路:
方法一: 遍历两次单链表,第一次遍历求出链表长度记为len, 第二次遍历找到第len - k个节点并输出即可。
复杂度分析: 时间复杂度 O(N), 空间复杂度 O(1)
1 | ListNode* getKthFromEnd(ListNode* head, int k) { |
方法二: 双指针法,设指针p, q,初始时将p指向链表头节点,q指向第k+1个节点,然后让p, q指针等速前进,当q为NULL时, p即为所求。
复杂度分析: 时间复杂度 O(N), 空间复杂度 O(1)
1 | ListNode* getKthFromEnd(ListNode* head, int k) { |
反转链表
以下给出两种思路:
方法一: 遍历原链表,依次对每个节点用头插法创建新链表并返回。
复杂度分析: 时间复杂度 O(N), 空间复杂度O(N)
1 | ListNode* reverseList(ListNode* head) { |
方法二: 迭代法,遍历单链表,依次改变每个节点的next指向即可。注意next指向改变后,就无法访问下一个节点了,所以要在改next指针之前,用一个临时指针保存next指向的节点。
复杂度分析: 时间复杂度 O(N), 空间复杂度O(1)
1 | ListNode* reverseList(ListNode* head) { |