Datawhale|LeetCodeTencent Task11(lc136,141, 142)

本文介绍了两种利用位运算和链表遍历解决算法问题的方法。一是通过位运算在O(n)时间复杂度内找到数组中唯一出现一次的数字,二是使用快慢指针判断链表是否存在环并定位环的入口。这些技巧在解决数据结构和算法问题时非常实用。
摘要由CSDN通过智能技术生成

136. Single Number(E)

Description

在这里插入图片描述

Analysis & Solution

要求只用 O ( n ) O(n) O(n)的时间复杂度,且不用额外空间。可以巧妙地运用位运算。
(1)相同数字位运算为1
(2)不同数字位运算为0
(3)非零整数与0位运算为整数本身
(4)位运算满足交换律
根据以上几条性质,数组中出现两次的数字进行位运算,结果为0。0与剩下的出现一次的数位运算就得该数本身。因此数组中所有元素位运算的结果就是本题目要求的输出。

Code

int singleNumber(vector<int>& nums)
{
    int res = 0;
    for(auto &p : nums)
        res = res ^ p;
    return res;
}

时间复杂度:遍历一次, O ( n ) O(n) O(n)

141. Linked List Cycle(E)

Description

在这里插入图片描述

Analysis & Solution

判断链表是否有环,可使用快慢指针。
快指针从head开始,每次移动两步;慢指针从head开始每次移动一步。若链表无环,则快指针先到达末尾,指向NULL;若链表有环,则经过若干轮遍历,快慢指针必然会相遇。

Code

bool hasCycle(ListNode* head)
{
    if(head == NULL || head->next == NULL) return false;
    ListNode* fast = head->next, * slow = head;
    while(fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow) return true;
    }
    return false;
}

时间复杂度:常数次遍历就可以得到结果,时间复杂度为 O ( n ) O(n) O(n)

142. Linked List Cycle II(M)

Description

在这里插入图片描述

Analysis & Solution

不仅要判断,链表是否有环,还要判断链表环出现的位置。设a的下一个位置是环节点,总节点数为a+b。
首先令快慢指针fast和slow进行移动,判断是否有环。由于fast移动距离是slow的两倍,且fast比slow多走了nb,因此slow走的距离是nb,fast为2nb。(n为正整数)
令指针p指向head,令p和slow同步移动,当p移动到a位置时,slow移动总距离为a+nb,这时p和slow恰好相遇。该位置就是题目所求位置。

Code

ListNode* detectCycle(ListNode* head)
{
    bool hasCycle = false;
    ListNode* fast = head, * slow = head;
    while(fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow)
        {
            hasCycle = true;
            break;
        }
    }
    if(hasCycle)
    {
        ListNode* p = head;
        while(p != slow)
        {
            p = p->next;
            slow = slow->next;
        }
       return p; 
    }
    else return NULL;   
}

时间复杂度:常数次遍历就可以得到结果,时间复杂度为 O ( n ) O(n) O(n)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值