0
点赞
收藏
分享

微信扫一扫

剑指offer-找出数组中重复的数字

码农K 2022-04-26 阅读 74
java

题目导航


前言

刷题冲Java实习,每天坚持刷题!点击题目可以跳转到 leetcode 相应题目


1.找出数组中重复的数字

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

限制 :2 <= n <= 100000

分析:

假设数组nums为:[0,3,2,1,3,4]
而且题目限制数组中数据的大小在0到n-1,数组长度为n。
那么我们可将数组的下标映射成对应的元素是否为存在过。

思考一下:

  1. 例如,nums[1] = 3
  2. 将数值存储到temp,temp=nums[1]
  3. 判断 nums[temp] 是否为负数,若是,则输出 temp
  4. 若不是则设置 nums[temp] 为其相反数,标识这个数值存在。nums[temp]*=-1;
  5. 循环1234步。

带入数组nums试试 nums:[0,3,2,1,3,4]

  1. 因为 nums[1]=3
  2. 设置 nums[3]为相反数= -1
  3. 因为 nums[4]=3
  4. 判断 num[3]是否小于0(小于0则说明之前已将查询过对应原始元素3)
  5. 小于0,输出 nums[3]

动图理解
请添加图片描述
但是很快我们就发现,当第一位数字为0的时候,第4步是执行了跟没执行一样,找不到0的存在,所以我们现在开始寻找相同数字之前,将数组遍历,全体数据+1。使得所有数据都是正数,取相反数之后可以成为负数。在输出和比对的时候只需要将结果-1即可。


实现代码:

class Solution {
   public int findRepeatNumber(int[] nums) {
       for (int i = 0; i < nums.length ; i++){//因为0*-1还=0,所以变正数,范围(1,n)
            nums[i]++;
       }
        for (int i = 0; i < nums.length ; i++) {
            int temp = Math.abs(nums[i])-1;//nums[i]可能为负(为负是因为这个下标对应的元素出现过了),所以用绝对值表示
            if (nums[temp]<0) return temp;//temp==Math.abs(nums[i])-1==原数字
            nums[temp] *= -1 ;//将原数字对应的下标设置为复数
        }
        return 0;
    }
}

补充一下:怕大家不理解,我还是以数组nums为:[0,3,2,1,3,4]为例子来 粗略 分析一下。

数组数据循环加1之后nums=[1,4,3,2,4,5]

  1. 因为 nums[1]=4,对应原元素为4-1=3
  2. 设置 nums[3]为相反数= -2
  3. 因为 nums[4]=4,对应原元素为4-1=3
  4. 判断 num[3]是否小于0(小于0则说明之前已将查询过对应原始元素3)
  5. 小于0,输出 nums[4]-1,对应原元素数据为nums[4]-1=3

byebye,为了做动图顺手学了一下flash哈哈哈

举报

相关推荐

0 条评论