NC 链表相关 - 3,4,53

NC4. 判断链表是否有环

题目描述

难度 的⭐
判断给定的链表中是否有环。如果有环则返回true,否则返回false。
你能给出空间复杂度为O(1)的解法么?

思路

使用快指针、慢指针方法,快指针一次移动两格,慢指针一次移动一格,总之,如果有环的话,它俩早晚有一天会碰上。

class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode *slow = head;
        ListNode *fast = head;
        while(slow && fast && fast->next){
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast)
                return true;
        }
        return false;
    }
};

NC3. 链表环的入口节点

难度 ⭐⭐

题目描述

对于一个给定的链表,返回环的入口节点,如果没有环,返回null
拓展:
你能给出不利用额外空间的解法么?

思路

这道题是上一道题的扩展:如果知道有环,那么入口的位置在哪呢?可以先画一个图:
在这里插入图片描述
假设图中存在环且快慢指针在z处相遇,此时慢指针走了a+b,快指针走了a+(b+c)*n,推出a=n(b+c)-b,因此让两个指针分别从起始点X和相遇点Z以相同速度前进,两个指针再次相遇的位置即为环的入口节点Y。

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* slow = head;
        ListNode* fast = head;
        while(slow && fast && fast->next){
            slow = slow->next;
            fast = fast->next->next;
            if(slow == fast){
                ListNode *slow2 = head;
                while(slow && slow2){
                    if(slow == slow2)
                        return slow;
                    slow = slow->next;
                    slow2 = slow2->next;
                }
            }
        }
        return NULL;
    }
};

NC53. 删除链表的倒数第n个节点

难度⭐⭐

题目描述

给定一个链表,删除链表的倒数第 n 个节点并返回链表的头指针。
例如,
给出的链表为: 1→2→3→4→5, n= 2
删除了链表的倒数第 n 个节点之后,链表变为1→2→3→5.

思路

为了找到“倒数第n个”节点,可以让一个快指针先出发n步。同时考虑到删除第一个节点的情况,因此应该增加一个哨兵“头”。

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @param n int整型 
     * @return ListNode类
     */
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        // write code here
        ListNode* head0 = new ListNode(-1);
        head0->next = head;
        ListNode* fast = head0;
        ListNode* slow = head0;
        for(int i = 0;i<n;i++)
            fast = fast->next;
        while(fast->next){
            fast = fast->next;
            slow = slow->next;
        }
        cout<<slow->val;
        if(slow->next){
            ListNode* tmp_next_next = slow->next->next;
            slow->next = tmp_next_next;
            return head0->next;
        }
        if(slow){
            slow->next = NULL;
            return head0->next;
        }
        
        return head0->next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值