找出数组中任一重复的数字

找出数组中任一重复的数字

找出数组中任一重复的数字

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

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



低效解法

方法一

# python
class Solution:
    def findRepeatNumber(self, nums):
        # 时间复杂度太高,O(N2)
        nums_set = set(nums)
        for i in nums_set:
            for j in nums:
                if i == j:
                    nums.remove(j)
                    break
        # nums包含所有重复元素
        return nums[0]

时间复杂度: O ( N 2 ) O(N^2) O(N2)
空间复杂度: O ( N ) O(N) O(N)

一般解法

方法二

// java
public int findRepeatNumber(int[] nums) {
    Arrays.sort(nums);
    int n = nums.length;
    int result = 0;
    for (int i = 0; i < n - 1; i++) {
        if (nums[i] == nums[i + 1]) {
            result = nums[i];
            break;
        }
    }
    return result;
}
# python
		nums.sort()
		for i in range(len(nums)-1):
		    if nums[i] == nums[i+1]:
		        return nums[i]

python list sort() 基于排序算法Timsort,时间复杂度为: O ( n l o g n ) O(n log n) O(nlogn),空间复杂度为: O ( n ) O(n) O(n)
python sort函数内部实现原理

时间复杂度: O ( n l o g n ) O(n log n) O(nlogn)
空间复杂度: O ( n ) O(n) O(n)

方法三

基于HashSet,依次遍历数组元素,插入集合中,如果无法插入,则为重复元素。

HashSet集合:不允许存储重复的元素,查询速度快

算法步骤

  1. 初始化一个哈希表 (HashSet)
  2. 遍历数组中每一个元素,分别对每一个元素做如下的处理:
  3. 将元素插入哈希表
    1. 如果不可插入,则该元素为重复元素,返回该元素
    2. 如果可插入,则判断下一个元素
    // 效率较低
    public int findRepeatNumber(int[] nums) {
        Set<Integer> set = new HashSet<Integer>();
        int repeat = 0;
        for (int i: nums) {
            if (!set.add(i)){
                repeat = i;
                break;
            }
        }
        return repeat;
    }

时间复杂度: O ( N ) O(N) O(N)
空间复杂度: O ( N ) O(N) O(N)



算法步骤:

  1. 初始化一个哈希表 (HashSet)
  2. 遍历数组中每一个元素,分别对每一个元素做如下的处理:
  3. 先判断哈希表中是否存在这个元素
    1. 如果存在的话,则说明这个元素重复,则直接返回
    2. 否则,将这个元素加入到哈希表中,方便后续的判重
    public int findRepeatNumber(int[] nums) {
        HashSet<Integer> set = new HashSet<Integer>();
        for (int i: nums) {
            // 判断元素是否存在
            if (set.contains(i)) {
                return i;
            }
            set.add(i);
        }
        return -1;
    }
}

set.contains()、set.add()时间复杂度为O(N)
Java:Set 的 contains() 方法 时间复杂度

时间复杂度是:O(n)
空间复杂度是:O(n)


方法四:原地置换算法–目前的最优解

原地置换算法详解及其应用

使用条件
  1. 元素个数为n,元素值范围为:[0,n-1]
  2. 用于重复出现的数,缺失的数等题目
理解

每个元素都有自己的位置(该元素的下标,如元素0的位置应该是下标为0),如果一组数(元素个数为n,元素值范围为:[0,n-1])中缺失或重复,则表现为有空位或位置重复匹配

原地置换算法-视频-作者:chefyuan

思路
  • 判断数组是否为空
  • 为空
  • 非空
    • 依次判断该下标对应的元素是否为指定元素
      • 不在
        • 判断该元素真正的位置在哪儿?
          • 相等(该元素和其真正位置上的元素相等)
            • 找到重复元素
          • 不等
            • 交换该元素和其正确位置上的元素
// java
	public int findRepeatNumber4(int[] nums) {
	    // 判断数组为空是否需要?
	    if (nums.length == 0){
	        return -1;
	    }
	    for (int i = 0; i < nums.length; i++) {
	        while (nums[i] != i){
	            if (nums[i] == nums[nums[i]]){
	                return nums[i];
	            }
	            int temp = nums[i];
	            nums[i] = nums[temp];
	            nums[temp] = nums[i];
	        }
	    }
	    return -1;
	}

TODO:分析
时间复杂度:
空间复杂度:

		# python转写
        if len(nums) == 0:
            return -1
        for i in range(len(nums)):
            while nums[i] != i:
                if nums[i] == nums[nums[i]]:
                    return nums[i]
                temp = nums[i]
                nums[i] =nums[temp]
                nums[temp] = temp
        return -1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值