如何判断数组所有数都不等于一个数_面试题 3 :数组中重复的数字

593e9dfd6d16d83eec972335744d8c56.png

面试题 3 :数组中重复的数字


leetcode-cn 题目地址

difficulty:Easy

Tags:

  • 哈希表
  • 数组

1. 题目描述

题目一

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

2. 解题思路

排序法

简单直接。

时间复杂度为:

public int findRepeatNumber(int[] nums) {
    if (nums == null || nums.length == 0) {
        return -1;
    }

    for (int num : nums) {
        if (num < 0 || num > nums.length - 1) {
            return -1;
        }
    }

    Arrays.sort(nums);
    for (int i = 0; i < nums.length - 1; i++) {
        if (nums[i] == nums[i + 1]) {
            return nums[i];
        }
    }
    return -1;
}

交换法

public int findRepeatNumber(int[] nums) {
    if (nums == null || nums.length == 0) {
        return -1;
    }

    for (int num : nums) {
        if (num < 0 || num > nums.length - 1) {
            return -1;
        }
    }

    int t;
    // 交换法,期望使得每一个元素落在其 index 的位置上
    for (int i = 0; i < nums.length; i++) {
        while (i != nums[i]) {
            if (nums[i] == nums[nums[i]]) {
                return nums[i];
            }
            t = nums[i];
            nums[i] = nums[t];
            nums[t] = t;
        }
    }
    return -1;
}

对于例子:{2,3,1,0,2,5,3} 。按照上述的算法进行分析:

  • 绕过特判。
  • i = 0 时,0 == nums[0] 不成立,且第 0 个数字不等于第 2 个位置上的数字。交换法,数组变为 {1,3,2,0,2,5,3}
    • 第 0 个数字不为 0 ,继续交换和判断。数组变为 {3,1,2,0,2,5,3}
    • 第 0 个数字不为 0 ,继续交换和判断,数组变为{0,1,2,3,2,5,3}
    • 第 0 个数字为 0,结束第 i 个数字的交换操作。(一共交换了 2 次。)
  • 后面的 {1,2,3} 位置正确,无需交换操作。
  • i = 4 时,4 不等于 nums[4]nums[4] 等于 2nums[2] 等于 2,即 nums[i] == nums[[nums[i]]] 成立,即出现了重复的数字,返回该数字。

复杂度分析

  • 时间复杂度
    • 虽然有 2 重循环,但是有个很巧的规律,每个数找到其对应的位置,最多只需要 2 次。如果一个数字是不重复的,那么交换 2 次后就会归位,否则就会出现重复,返回改数字即可。
    • 即复杂度为 O(n)
  • 空间复杂度
    • O(1)

3. 总结

善于寻找规律,尤其要分析出 :每个数找到其对应的位置,最多只需要 2 次交换。

可以使用一个具体的例子去分析问题,寻找规律。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值