首页 > 编程语言 >【剑指 Offer】数组中重复的数字(C++_Easy_遍历/哈希/快排/原地)

【剑指 Offer】数组中重复的数字(C++_Easy_遍历/哈希/快排/原地)

时间:2023-06-20 11:39:18浏览次数:53  
标签:位置 return nums int Offer 数值 vector C++ 哈希


题目

在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。

测试样例

输入:
[2, 3, 1, 0, 2, 5, 3]
输出:2 或 3

限制

2 <= n <= 100000

题解

题解一:遍历

对vector容器中的数值进行逐个遍历,并把检查过的数值在数组中标记出来,如果数值已经被标记过则返回该值。

int findRepeatNumber(vector<int>& nums) {
        int a[1000010]={0};
        int n = nums.size();
        vector<int>::iterator it;
        for (it = nums.begin(); it != nums.end(); it++){
            if(a[*it] > 0)
                return *it;
            else
                a[*it]++;
        }        
        return -1;
    }

题解二:原地算法

首先理解每个萝卜都只有唯一的属于自己的坑。因为每个数值只能出现一次,一旦出现多次就要输出该值,那么我们把索引和数值对应起来,比如:nums[0]的位置就对应着0这个数值,一旦在nums[0]的位置出现了数值k,那么就交换nums[0]和nums[k],保证数值k和其位置对应。
再来说程序的问题。我们有三种情况:

  • 要么数值和位置对应,不用做改变,继续向后遍历即可;
  • 要么数值和位置不对应,要进行交换,但是在交换的过程中还要判断你要找的位置是不是已经有对应的萝卜占了(在这一步不能持续向后遍历,只有第一种情况才能挪动指针);
  • 如果已经有同样符合要求的数值在那个对应的位置了,那么就说明该值重复了,输出该值!举个例子:

nums={0, 1, 2, 1}
其中nums[0], nums[1]=1, nums[2]=2,这些都是没有问题的,但是nums[3]却不等于3,其数值为1,那么就找1对应的nums[1],结果发现nums[1]已经等于1了,那么这个时候就说明nums[3]位置的数值1重复了。

  • 如果要交换的位置同样不匹配,那么交换就好了。举个例子:

nums={1, 2, 1}
nums[0]=1,那么就直接找nums[1]位置,nums[1]位置也不是对应的数值1,那么直接交换即可,交换后为:nums={2,1,1}。

int findRepeatNumber(vector<int>& nums) {
        int n=nums.size(), i=0;
        while(i<n){
            if(nums.at(i)==i){//符合要求
                i++;
                continue;
            }
            else if(nums.at(i)==nums.at(nums.at(i)))
                return nums.at(i);
            else
                swap(nums.at(i), nums.at(nums.at(i)));
        }
        return -1;
    }

题解三:快速排序

对数值排个序,连续重复的就是要输出的点。

int findRepeatNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n=nums.size(), temp=nums[0];
        for(int i=1; i!=n; i++)
            if(temp==nums[i])
                return temp;
            else
                temp=nums[i];
        return -1;
    }

题解四:哈希表

把数值挨个放入哈希表中,出现重复就输出。

int findRepeatNumber(vector<int>& nums) {
        unordered_set<int> s;
        int n=nums.size(), t=0;
        for(int i=0;i!=n;i++){
            t=nums[i];
            if(s.count(t)==0)
                s.insert(t);
            else
                return t;
        }
        return -1;
    }

创作不易,点个赞再走嘛(*^_^*)


标签:位置,return,nums,int,Offer,数值,vector,C++,哈希
From: https://blog.51cto.com/u_16165815/6521610

相关文章

  • 【计算机算法设计与分析】线性时间选择(C++_分治递归)
    问题描述给定线性序集中n个元素和一个整数k,1≤k≤n,要求找出这n个元素中第k小的元素。思路线性时间选择有两种方法:(1)随机选择快排的标准元素。(2)将集合分为n个由五个元素组成的集合,对每个五元素集合求其中位数,再对所有的五元素集合的中位数求其中位数,作为快排的标准元素。CodeV-1(Ran......
  • 【剑指 Offer】用两个栈实现队列(C++_Easy_栈/队列)
    1.题目用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead操作返回-1)2.示例2.1示例1输入:[“CQueue”,“appendTail”,“deleteHead”,“deleteHead”......
  • 【计算机算法设计与分析】6-5 最小重量机器设计问题(C++_回溯法/分支限界法)
    问题描述设某一机器由n个部件组成,每一种部件都可以从m个不同的供应商处购得。设wij是从供应商j处购得的部件i的重量,cij是相应的价格。设计一个优先队列式分支限界法,给出总价格不超过d的最小重量机器设计。对于给定的机器部件重量和机器部件价格,设计一个优先队列式分......
  • 【蓝桥杯_真题演练】换零钞(C++_遍历)
    题目x星球的钞票的面额只有:100元,5元,2元,1元,共4种。小明去x星旅游,他手里只有2张100元的x星币,太不方便,恰好路过x星银行就去换零钱。小明有点强迫症,他坚持要求200元换出的零钞中2元的张数刚好是1元的张数的10倍,剩下的当然都是5元面额的。银行的工作人员有点为难,你能帮助算出:在满足小......
  • 【蓝桥杯_真题演练】第九届C/C++省赛B组_C-乘积尾零(C++_数论)
    Problem如下的10行数据,每行有10个整数,请你求出它们的乘积的末尾有多少个零?56504542355447394641143871907390432927587949611356595245743230514434670435949937117368663397475975573070228714539899148657223135117040145510512072928809......
  • PTA_乙级_1015 德才论(C++_模拟_快排)
    宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”现给出一批考生的德才分数,请根据司马光的理论给出录取排名。输入格式:输入第一行给出3个......
  • P3371 【模板】单源最短路径(弱化版)(C++_SPFA算法_链式向前星)
    题目背景本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步P4779。题目描述如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。输入格式第一行包含三个整数n,m,s,分别表示点的个数、有向边的个数、出发点的编号。接下来m行每行包含三个......
  • C++ primer plus学习之第二章
    1.引用:intival=1024;int&refval=ival;//正确,refval时ival的别名int&re;//错误,引用必须被初始化int&ii=42;//错误:不能为非常量引用绑定字面值constint&ii=42;//正确:可以为常量引用绑定字面值2.初始化空指针int*p=0;int*p=NULL;int*p=nullptr;//最好用这个任何非零指......
  • 总结C++中#include<>和#include""的区别
    查找目录不同1、#include<>编译器直接从系统类库目录里查找头文件比如在vs中,使用#include<>编译器会直接在vs安装目录下在编译器自带的库文件中进行搜索。如果类库目录下查找失败,编译器会终止查找,直接报错:Nosuchfileordirectory.如果我们自定义一个头文件"aaa.h",将其放在......
  • CCF_201912-1 报数(C++_模拟)
    思路代码可能写的有点啰嗦冗余,写的时候有点急写完一节就直接复制粘贴了蛤蛤蛤,所以导致中间有些代码比较重复。Code#include<bits/stdc++.h>//模拟usingnamespacestd;intn,sum=0,a,b,c,d;booljudge(ints){ inttemp=s; if(temp%7==0) return0; while......