每日一题(day7)

一、链表中环的入口结点

描述

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,返回null。

输入描述:

输入分为2段,第一段是入环前的链表部分,第二段是链表环的部分,后台将这2个会组装成一个有环或者无环单链表

返回值描述:

返回链表的环的入口结点即可。而我们后台程序会打印这个节点

解题思路:

1.采用快慢指针进行求解
如果链表存在环,则fast和slow会在环内相遇,定义相遇点到入口点的距离为X,定义环的长度为C,定义头到入口的距离为L,fast在slow进入环之后一圈内追上slow,则会得知:
slow所走的步数为:L + X
fast所走的步数为:L + X + N * C
并且fast所走的步数为slow的两倍,故:
2*(L + X) = L + X + N * C
即: L = N * C - X
所以从相遇点开始slow继续走,让一个指针从头开始走,相遇点即为入口节点

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        if(pHead==nullptr||pHead->next==nullptr)
            return nullptr;
        
        ListNode* slow=pHead;
        ListNode* fast=pHead;
        
        while(fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast)
            {
                fast=pHead;
                while(fast!=slow)
                {
                    fast=fast->next;
                    slow=slow->next;
                }
                return fast;
            }
        }
        return nullptr;
        
    }
};

2.采用哈希进行求解

将链表中结点依次存入哈希中:如果该节点不存在则存入哈希中,如果存在相同结点,则证明该链表中有环,并且该节点为入口第一个节点。

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead) {
        if(pHead==nullptr||pHead->next==nullptr)
            return nullptr;
        unordered_map<ListNode*,int> hash;
        while(pHead->next)
        {
            if(hash.find(pHead)==hash.end())
            {
                hash[pHead]++;
            }
            else
            {
                return pHead;
            }
            pHead=pHead->next;
        }
        return nullptr;
        
    }
};

二、括号序列

描述

给出一个仅包含字符'(',')','{','}','['和']',的字符串,判断给出的字符串是否是合法的括号序列
括号必须以正确的顺序关闭,"()"和"()[]{}"都是合法的括号序列,但"(]"和"([)]"不合法

class Solution {
public:
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    bool isValid(string s) {
        // write code here
        stack<char> st;
        for(auto& e:s)
        {
            if(e=='[')
                st.push(']');
            else if(e=='{')
                st.push('}');
            else if(e=='(')
                st.push(')');
            else
            {
                if(st.empty())
                    return false;
                if(st.top()==e)
                    st.pop();
            }
        }
        return st.empty();
    }
};

三、删除链表的倒数第n个节点

描述

给定一个链表,删除链表的倒数第 nn 个节点并返回链表的头指针
例如,

给出的链表为: 1\to 2\to 3\to 4\to 51→2→3→4→5, n= 2n=2.
删除了链表的倒数第 nn 个节点之后,链表变为1\to 2\to 3\to 51→2→3→5.
备注:

题目保证 nn 一定是有效的
请给出时间复杂度为\ O(n) O(n) 的算法

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // write code here
        if(!head||!head->next)
            return nullptr;
        
        ListNode*slow,*fast,*pre;
        slow=fast=pre=head;
        
        for(int i=0;i<n;i++)
        {
            fast=fast->next;
        }
        if(!fast)
            return head->next;
        
        while(fast)
        {
            pre=slow;
            fast=fast->next;
            slow=slow->next;
        }
        pre->next=slow->next;
        delete slow;
        return head;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ishao97

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值