找出1到n中重复的数字

问题描述

在数组nums[n + 1]中,数字都是1到n范围内的,那么至少有一个重复数字,找到它。

 

解法1 排序法 时间O(nlgn) 空间O(n)

public static int duplicate(int[] nums){
	if(null == nums || nums.length == 0){
		return Collections.emptyList();
	}
	
	Arrays.sort(nums);
	for(int i = 1; i < nums.length; i++){
		if(nums[i - 1] == nums[i]){
			return nums[i];
		}
	}

	return -1;
}

 

解法2 Hash法 时间O(n) 空间O(n)

public static List<Integer> duplicate(int[] nums){
	if(null == nums || nums.length == 0){
		return Collections.emptyList();
	}

	HashSet<Integer> set = new HashSet<Integer>();
	List<Integer> result = new ArrayList<Integer>();
	for(int i = 0; i < nums.length; i++){
		if(set.contains(nums[i])){
			return nums[i];
		}else{
			set.add(nums[i]);
		}
	}

	return -1;
}

解法3 标记法 时间O(n) 空间O(1)

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

    for(int i = 0; i < nums.length; i++){
        int next = nums[i] - 1;
        //遍历过程中,已经指过,也就是已经遍历过等于 i+1 的数
        if(nums[i] > nums.length){
            next -= nums.length;
        }

        if(nums[next] > nums.length){
            return next + 1;
        }else{
            //加 n(数组长度) 作为标记
            nums[next] += nums.length;
        }
    }

    return -1;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值