二刷LeetCode--160. 相交链表、169. 多数元素、141. 环形链表(C++版本)

文章介绍了三道关于链表的算法题目,包括如何找到两个链表的交点,通过快慢指针判断环形链表,以及找出数组中的多数元素。解题策略涉及到从后向前遍历、栈的应用、哈希映射以及快慢指针等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

160. 相交链表
复习知识点:本题属于思路题,主要考虑从起始点到交点的距离,或者使用从后向前进行寻找不相等的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        // 首先可以想到从后向前遍历,碰到不相等的元素就退出,因此使用栈
        stack<ListNode*> p1, p2;
        for(ListNode* p = headA;p != nullptr;p = p -> next)
            p1.push(p);
        for(ListNode* q = headB;q != nullptr;q = q -> next)
            p2.push(q);
        ListNode* res = nullptr;
        // 当两个栈非空并且顶端的元素相等的时候进行循环
        for(;!p1.empty() && !p2.empty() && p1.top() == p2.top(); p1.pop(), p2.pop())
            res = p1.top();
        return res;
    }
};
// 此题也可以利用两个链表分别从表头第二次经过相交节点的距离相同进行解答
// 即走到末尾的时候从另一个链表的头部开始继续向后,那么就会在相交位置相遇

169. 多数元素
复习知识点:本题与上面的题一样,属于思路类,可以通过排序,将位于一半位置的元素返回,该元素一定是多数元素。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        unordered_map<int, int>hash;
        for(int num : nums)
        {
            ++hash[num];
            if(hash[num] > nums.size() / 2)
                return num;
        }
        return 0;
    }
};
// 本题也可以通过排序,中间位置上的元素一定是多数元素,直接返回即可

141. 环形链表
复习知识点:链表成环在使用快慢指针时需要将快指针首先向前走一步然后进行判空与是否和慢指针相等判断。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        if(head == nullptr || head -> next == nullptr)
            return false;
        ListNode* fast = head -> next;
        ListNode* slow = head;
        while(fast != slow)
        {
            // 如果其中一个走到末尾了说明没有环
            if(fast == nullptr || fast -> next == nullptr)
                return false;
            fast = fast -> next -> next;
            slow = slow -> next;
        }
        return true;
    }
};
// 本题也可以通过将已经访问过的数据进行存储,如果该数字被访问两次,那么该链表成环
### LeetCode C++ 实现两个链表相交问题的解决方案 以下是基于提供的引用以及专业知识设计的一个完整的解决方案。此方案通过计算两链表长度差并调整起始位置来找到第一个公共节点。 #### 解决方案概述 为了高效解决该问题,可以采用双指针法,在不改变原结构的情况下完成操作。具体逻辑如下: 1. 计算两条链表的长度 `lenA` 和 `lenB`。 2. 将较长链表的头指针向前移动两者长度之差的距离。 3. 同步遍历两条链表直到发现相同节点或者到达尾部。 这种方法的时间复杂度为 \(O(m+n)\),空间复杂度为 \(O(1)\)[^3]。 #### 完整代码实现 (C++) ```cpp #include <iostream> using namespace std; // Definition for singly-linked list. struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(nullptr) {} }; class Solution { public: ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) { if (!headA || !headB) return nullptr; // Step 1: Calculate lengths of both lists int lenA = getListLength(headA); int lenB = getListLength(headB); // Step 2: Align the start point by moving longer list's pointer forward while (lenA > lenB) { headA = headA->next; --lenA; } while (lenB > lenA) { headB = headB->next; --lenB; } // Step 3: Traverse both lists together until an intersection is found or end reached while (headA && headB) { if (headA == headB) return headA; // Found intersection headA = headA->next; headB = headB->next; } return nullptr; // No intersection exists } private: int getListLength(ListNode* head) const { int length = 0; while (head) { ++length; head = head->next; } return length; } }; ``` 上述代码实现了寻找两个单向链表首个公共节点的功能[^4]。它首先分别获取两个链表的长度,并让较长的那个先前进几步以使剩余部分等长;接着同步推进直至找到共同节点或结束循环返回空值表示无交叉情况发生[^5]。 #### 关键点解析 - **时间效率**: 整体算法仅需两次线性扫描即可得出结论,因此满足题目提出的性能需求即运行时间为\(O(n)\)- **空间节省**: 不需要额外存储辅助数据结构,整个过程只用了固定数量变量保存临时状态信息,故达到常数级内存消耗标准\[O(1)]\. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值