【2023】字节跳动 10 日心动计划——第六关

目录

  • [1. 环形链表 II](#1. 环形链表 II)
  • [2. 有序数组中的单一元素](#2. 有序数组中的单一元素)

1. 环形链表 II

🔗 原题链接:142. 环形链表 II

用哈希表判重即可。

cpp 复制代码
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> st;
        while (head) {
            if (st.count(head)) return head;
            st.insert(head);
            head = head->next;
        }
        return nullptr;
    }
};

2. 有序数组中的单一元素

🔗 原题链接:LCR 070. 有序数组中的单一元素

这里介绍两种做法。

方法一:异或。注意到 x ⊕ x = 0 x\oplus x=0 x⊕x=0,因此 ⊕ i = 1 n n u m s [ i ] \oplus_{i=1}^nnums[i] ⊕i=1nnums[i] 就是最终答案。

cpp 复制代码
class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int ans = 0;
        for (auto& num: nums) ans ^= num;
        return ans;
    }
};

方法二:二分。注意到数组是有序的,因此我们可以用二分去处理,时间复杂度可以降至 O ( log ⁡ n ) O(\log n) O(logn)。

不妨设只出现一次的元素的下标是 x x x,由题意可知下标 x x x 的左右两边各有偶数个元素,从而 x x x 是偶数,且数组的长度是奇数,不妨设为 n n n。

既然要用二分,那我们就需要找到一个性质能够将区间 [ 0 , n − 1 ] [0,n-1] [0,n−1] 一分为二。注意到 ∀ i ∈ [ 0 , x − 1 ] \forall i\in[0,x-1] ∀i∈[0,x−1],如果 n u m s [ i ] = n u m s [ i + 1 ] nums[i]=nums[i+1] nums[i]=nums[i+1],那么 i i i 一定是偶数; ∀ i ∈ [ x , n − 1 ] \forall i\in[x,n-1] ∀i∈[x,n−1],如果 n u m s [ i ] = n u m s [ i + 1 ] nums[i]=nums[i+1] nums[i]=nums[i+1],那么 i i i 一定是奇数。

更进一步, ∀ i ∈ [ 0 , n − 1 ] \forall i\in[0,n-1] ∀i∈[0,n−1],如果 i i i 是偶数,我们判断 n u m s [ i ] nums[i] nums[i] 和 n u m s [ i + 1 ] nums[i+1] nums[i+1] 是否相等,如果相等,则 i ∈ [ 0 , x − 1 ] i\in[0,x-1] i∈[0,x−1],否则 i ∈ [ x , n − 1 ] i\in[x,n-1] i∈[x,n−1];如果 i i i 是奇数,则 i − 1 i-1 i−1 是偶数,我们判断 n u m s [ i − 1 ] nums[i-1] nums[i−1] 和 n u m s [ i ] nums[i] nums[i] 是否相等,如果相等,则 i ∈ [ 0 , x − 1 ] i\in[0,x-1] i∈[0,x−1],否则 i ∈ [ x , n − 1 ] i\in[x,n-1] i∈[x,n−1]。

注意到当 i i i 是偶数时, i + 1 = i ⊕ 1 i+1=i\oplus1 i+1=i⊕1,当 i i i 是奇数时, i − 1 = i ⊕ 1 i-1=i\oplus1 i−1=i⊕1,从而我们只需要判断 n u m s [ i ] nums[i] nums[i] 和 n u m s [ i ⊕ 1 ] nums[i\oplus 1] nums[i⊕1] 是否相等。条件 n u m s [ i ] ≠ n u m s [ i ⊕ 1 ] nums[i]\neq nums[i\oplus1] nums[i]=nums[i⊕1] 将区间 [ 0 , n − 1 ] [0,n-1] [0,n−1] 分成了两部分: [ 0 , x ) [0,x) [0,x) 和 [ x , n − 1 ] [x,n-1] [x,n−1],前者不满足这个条件,后者满足这个条件,所以我们可以套用寻找左边界的二分模版

cpp 复制代码
class Solution {
public:
    int singleNonDuplicate(vector<int>& nums) {
        int l = 0, r = nums.size() - 1;
        while (l < r) {
            int mid = l + r >> 1;
            if (nums[mid] != nums[mid ^ 1]) r = mid;
            else l = mid + 1;
        }
        return nums[r];
    }
};
相关推荐
初晴や1 小时前
【C++】图论:基础理论与实际应用深入解析
c++·算法·图论
李泽辉_1 小时前
深度学习算法学习(五):手动实现梯度计算、反向传播、优化器Adam
深度学习·学习·算法
李泽辉_1 小时前
深度学习算法学习(一):梯度下降法和最简单的深度学习核心原理代码
深度学习·学习·算法
꧁Q༒ོγ꧂1 小时前
算法详解---大纲
算法
m0_603888711 小时前
Scaling Trends for Multi-Hop Contextual Reasoning in Mid-Scale Language Models
人工智能·算法·ai·语言模型·论文速览
Xの哲學1 小时前
Linux io_uring 深度剖析: 重新定义高性能I/O的架构革命
linux·服务器·网络·算法·边缘计算
comli_cn1 小时前
残差链接(Residual Connection)
人工智能·算法
Aaron15882 小时前
基于VU13P在人工智能高速接口传输上的应用浅析
人工智能·算法·fpga开发·硬件架构·信息与通信·信号处理·基带工程
予枫的编程笔记2 小时前
【论文解读】DLF:以语言为核心的多模态情感分析新范式 (AAAI 2025)
人工智能·python·算法·机器学习
im_AMBER2 小时前
Leetcode 99 删除排序链表中的重复元素 | 合并两个链表
数据结构·笔记·学习·算法·leetcode·链表