剑指 Offer 03. 数组中重复的数字(不修改原数组)
https://www.acwing.com/problem/content/description/15/
显然此题可以用桶法做,空间换时间
class Solution {
public:
int duplicateInArray(vector<int>& nums) {
int a[1005]={0};
int n=nums.size();
for(int i=0;i<n;i++)a[nums[i]]++;
for(int i=0;i<n;i++)
if(a[nums[i]]>=2)
return nums[i];
return 0;
}
};
但是题目要求可以用o(1)的空间,这里可以用抽屉原理的性质二分划分二段性
即从中间划分两个不同区间,其中的数个数 由于有个重复的数在其中一个区间中,可以得出两个区间数的个数不同
由这种性质来二分,求出区间的数的个数的,较大值的区间为答案所在范围,不断二分选取即可,直到区间为1即得出答案
要注意的是,这里的二分区间,[l,mid]与[mid+1,r]均为值,而不是nums下标
class Solution {
public:
int duplicateInArray(vector<int>& nums) {
int l = 1, r = nums.size() - 1;
while (l < r) {
int mid = l + r >> 1;
int s = 0;
for (auto x : nums) s += x >= l && x <= mid;//遍历nums寻找左区间[l,mid]数的个数
if (s > mid - l + 1) r = mid;//左区间数的个数大于l~mid,即mid-l+1,即左区间为答案区间,右边界缩小
else l = mid + 1;//左边界增大
}
return r;
}
};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!