题目描述

在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。

题目分析与代码

题目比较简单,不过我想写下我的算法改进过程。

我第一眼看到就是打算用额外的数组或者hash记录下次数,然后再判断次数大于1的即为重复的,像这样。

  1. function duplicat(numbers, duplication) {
  2. // write code here
  3. // 这里要特别注意~找到任意重复的一个值并赋值到duplication[0]
  4. // 函数返回True/False
  5. const map = {};
  6. let flag = false;
  7. for (let i = 0; i < numbers.length; i++) {
  8. if (!map[numbers[i]]) {
  9. map[numbers[i]] = 1;
  10. } else {
  11. map[numbers[i]]++;
  12. }
  13. }
  14. for (const i in map) {
  15. if (map[i] > 1) {
  16. flag = true;
  17. duplication[0] = i;
  18. break;
  19. }
  20. }
  21. return flag;
  22. }

后来觉得第二个循环明显多次一举,我只需要知道出现次数大于1就行了,不需要知道所有数出现次数,于是有

  1. function duplicate(numbers, duplication) {
  2. const map = {};
  3. let flag = false;
  4. for (let i = 0; i < numbers.length; i++) {
  5. if (!map[numbers[i]]) {
  6. map[numbers[i]] = 1;
  7. } else {
  8. duplication[0] = numbers[i];
  9. flag = true;
  10. break;
  11. }
  12. }
  13. return flag;
  14. }

可是不对呀,题目的条件有个没有利用上呀:一个长度为n的数组里的所有数字都在0到n-1的范围内

说明算法还可以改进。

由于数组里的所有数字都在0到n-1,也就是值也在数组的下标范围里。

我们可以这样做,通俗来讲,就是把数组中的每个值放到对应的下标的位置上。(数归其标)

  1. 把当前序列当成是一个下标和下标对应值是相同的数组;
  2. 遍历数组,判断当前位的值和下标是否相等: 2.1. 若相等,则遍历下一位; 2.2. 若不等,则将当前位置i上的元素和a[i]位置上的元素比较:若它们相等,则成功,即找到了重复的值!若不等,则将它们两交换。换完之后a[i]位置上的值和它的下标是对应的,但i位置上的元素和下标并不一定对应;重复2.2的操作,直到当前位置i的值也为i,将i向后移一位,再重复2.

这个也是剑指上的做法,这种不需要额外空间,时间复杂度为O(n)

  1. // 第一种
  2. function duplicate(numbers, duplication) {
  3. for (let i = 0; i < numbers.length; i++) {
  4. while (i !== numbers[i]) {
  5. if (numbers[i] === numbers[numbers[i]]) {
  6. duplication[0] = numbers[i];
  7. return true;
  8. }
  9. [numbers[i], numbers[numbers[i]]] = [numbers[numbers[i]], numbers[i]]; // 交换
  10. }
  11. }
  12. return false;
  13. }

对了,还可以排序后,比较前后数字是否相同来做,不过这种方法时间复杂度不行,故舍去。

除此外,在牛客上还有种做法:

题目里写了数组里数字的范围保证在0 ~ n-1 之间,所以可以利用现有数组设置标志,当一个数字被访问过后,可以设置对应位上的数 + n,之后再遇到相同的数时,会发现对应位上的数已经大于等于n了,那么直接返回这个数即可。

  1. // 第二种
  2. function duplicate2(numbers, duplication) {
  3. for (let i = 0; i < numbers.length; i++) {
  4. let index = numbers[i];
  5. if (index >= numbers.length) {
  6. index -= numbers.length;
  7. }
  8. if (numbers[index] >= numbers.length) {
  9. duplication[0] = index;
  10. return true;
  11. }
  12. numbers[index] = numbers[index] + numbers.length;
  13. }
  14. return false;
  15. }

剑指offer(50)数组中重复的数字的更多相关文章

  1. 剑指Offer 50. 数组中重复的数字 (数组)

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  2. [剑指Offer] 50.数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  3. 剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知 ...

  4. 菜鸟刷题路:剑指 Offer 03. 数组中重复的数字

    剑指 Offer 03. 数组中重复的数字 哈希表/set class Solution { public int findRepeatNumber(int[] nums) { HashSet< ...

  5. 5.1 剑指 Offer 03. 数组中重复的数字

    类型题:剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字.在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了, ...

  6. 【剑指Offer】数组中重复的数字 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 Set 快慢指针 日期 题目地址:https://leetcod ...

  7. Go语言实现:【剑指offer】数组中重复的数字

    该题目来源于牛客网<剑指offer>专题. 在一个长度为n的数组里的所有数字都在0到n-1的范围内.数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组 ...

  8. (python)剑指Offer:数组中重复的数字

    问题描述 在长度为n的数组中,所有的元素都是0到n-1的范围内. 数组中的某些数字是重复的,但不知道有几个重复的数字,也不知道重复了几次,请找出任意重复的数字. 例如,输入长度为7的数组{2,3,1, ...

  9. 剑指offer:数组中重复的数字

    题目描述: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度 ...

  10. 【剑指offer】数组中重复的数字

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

随机推荐

  1. 27.用webpack自搭react和vue框架

    自己搭建react-app vue-cli 前置条件 cnpm i -D webpack webpack-cli webpack-dev-server cnpm i -D css-loader sty ...

  2. 关于c++深拷贝与浅拷贝

    首先看一段代码: #include<iostream> #include<cstring> #include<malloc.h> using namespace s ...

  3. 关于vue-cli创建项目(小白)

    vue-cli,都说是vue脚手架,一般cli是命令行的意思,一看就知道与node有关,其实脚手架是建筑工用的工具,给工人踩在上面干活的,这里借用它的意思,我觉得应该叫vue平台工具大家更容易懂,毕竟 ...

  4. Unity 为队伍设置不同颜色的shader

    在魔兽争霸等一些游戏中,我们通过模型的颜色就能很轻松的区分队伍,如下:   实现的方法有很多,比如: 1,为不同队伍各出一张不同颜色的贴图(Hmmm,war3有的地图可以容纳12只队伍,美术大大们会很 ...

  5. Codeforces 1136D - Nastya Is Buying Lunch - [贪心+链表+map]

    题目链接:https://codeforces.com/problemset/problem/1136/D 题意: 给出 $1 \sim n$ 的某个排列 $p$,再给出若干 $(x,y)$ 表示当序 ...

  6. 002-自定义打开terminal,以及快捷键,其他程序类似,ssh管理-sshpass, Shuttle

    一.利用Automator软件完成服务设定 1.使用Command+Space,打开Spotlight,搜索Automator 2.搜索到之后,双击打开,选择“服务[或快速操作]” 3.将“服务收到[ ...

  7. 后台管理界面admin

    admin组件:展示数据表,快速的录入数据. 为了安全,可以在路由分发时修改下admin的名字.(一定要改) 1.不想使用英文,则在app里的settings修改一下(在最下面的位置) LANGUAG ...

  8. 建立请求号 request

    1:获取TR号(一般由团队的负责人创建,发出) 2:进入 i7p系统 3:点击process 4:输入tr号 5:选中 正确的请求号,右键> process item> add task ...

  9. 【LeetCode每天一题】Length of Last Word(字符串中最后一个单词的长度)

    Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...

  10. window中的attrib命令

    attrib -s -h -r autorun.infattrib +s +h +r autorun.infattrib -s -h -r my.icoattrib +s +h +r my.ico