【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}^nnumsi ⊕i=1nnumsi 就是最终答案。

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\in0,x-1 ∀i∈0,x−1,如果 n u m s i = n u m s i + 1 numsi=numsi+1 numsi=numsi+1,那么 i i i 一定是偶数; ∀ i ∈ x , n − 1 \forall i\inx,n-1 ∀i∈x,n−1,如果 n u m s i = n u m s i + 1 numsi=numsi+1 numsi=numsi+1,那么 i i i 一定是奇数。

更进一步, ∀ i ∈ 0 , n − 1 \forall i\in0,n-1 ∀i∈0,n−1,如果 i i i 是偶数,我们判断 n u m s i numsi numsi 和 n u m s i + 1 numsi+1 numsi+1 是否相等,如果相等,则 i ∈ 0 , x − 1 i\in0,x-1 i∈0,x−1,否则 i ∈ x , n − 1 i\inx,n-1 i∈x,n−1;如果 i i i 是奇数,则 i − 1 i-1 i−1 是偶数,我们判断 n u m s i − 1 numsi-1 numsi−1 和 n u m s i numsi numsi 是否相等,如果相等,则 i ∈ 0 , x − 1 i\in0,x-1 i∈0,x−1,否则 i ∈ x , n − 1 i\inx,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 numsi numsi 和 n u m s i ⊕ 1 numsi\\oplus 1 numsi⊕1 是否相等。条件 n u m s i ≠ n u m s i ⊕ 1 numsi\neq numsi\\oplus1 numsi=numsi⊕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];
    }
};
相关推荐
alphaTao5 小时前
LeetCode 每日一题 2026/8/24-2026/8/30
python·算法·leetcode
Interview Aid1125 小时前
TikTok OA 四题分享|半小时内 AC,题目基本都是实现题
java·开发语言·算法·面试·职场和发展
顶点多余15 小时前
那些在算法中适合巩固的知识点---1
java·前端·算法
AI情绪识别开源15 小时前
检信 ALLEMOTION OS 加密打包可执行程序 — 全面测试报告版本: v1.3功能测试 / 性能测试 /
开发语言·数据结构·人工智能·功能测试
罗西的思考16 小时前
【Agentic RL / 强化学习框架】Molt 设计解读
人工智能·算法·机器学习
hahaha601617 小时前
HLS高层次综合设计技巧--C++类和模板
图像处理·人工智能·算法·计算机视觉
多弗朗皮卡丘18 小时前
算法详解4:买卖股票的最佳时机系列(上)
算法
维克兜率天20 小时前
【维克】动量指标家族:RSI、ROC、CCI、Momentum全面解析
python·算法
AI情绪识别开源21 小时前
检信 AI 智能推广平台(代号:JX-Promote)
人工智能·算法·erlang
老当益壮梁奶奶21 小时前
Linux软件编程学习笔记(八):进程间通信详解(1)
linux·c语言·笔记·学习·算法