剑指offer面试题3:数组中重复的数字(Java 实现)

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

方法一:时间复杂度为O(n*nlogn),空间复杂度为O(1)
先把输入的数组排序,排序一个长度为n的数组需要 O(nlogn)的时间,然后只需从头到尾扫描一次数组,需要 O(n)的时间,比较 a[i] 是否等于 a[i+1],若相等,则说明有重复的元素,输出 a[i] ,若不相等,说明数组中没有重复的元素。

方法二:时间复杂度O(n),空间复杂度O(n),以空间换时间
利用一个大小为O(n)的哈希表来解决问题,首先从头到尾扫描一次数组,时间复杂度为 O(n),每扫描一个元素都可以用 O(1)的时间来判断哈希表中有没有这个元素,若哈希表中没有这个元素,则把它加入到哈希表中,若哈希表中存在这个元素,说明这个元素重复了,就找到了一个重复的元素。

方法三:时间复杂度O(n),空间复杂度O(1)
首先从头到尾扫描数组,时间复杂度为 O(n),依次判断数组中的元素与其下标是否对应相等。当不相等时:分为两种情况,如果这个元素与以这个元素值为下标的元素相等(元素本应该在的位置),则说明这个元素重复了;若不相等,交换元素,把元素放到与其下标对应的位置。以数组{2,3,1,0,2,5,3,}为例,第0个元素(下标为0)值为2,与下标不对应相等,则在比较下标为2所在的元素,这里是1,不相等,即交换2和1,把2放回与下标对应的位置。

测试用例:

1、功能测试:长度为n的数组中包含一个或多个重复的数字。
2、边界测试:数组中不包含重复的数字
3、负面测试:输入空指针;长度为n的数组包含0——n-1之外的数字
 

import java.util.HashMap;

public class test_three {
	
	//方法二:利用一个大小为O(n)的哈希表
	public boolean duplicate(int numbers[],int length,int [] duplication) {
        boolean flag = false;
        if(numbers==null || length==0){
            return flag;
        }
        HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
        for(int num: numbers){
            if(map.containsKey(num)){
                flag = true;
                duplication[0] = num;
                break;
            }
            map.put(num, 0);
        }
        return flag;
    }
	
	/*
	 方法三:时间复杂度O(n),空间复杂度O(1) 最优解法:虽然代码中有一个二重循环,但每个数字最多只要交换两次就能找到属于它自己的
	 位置,因此总的时间复杂度是O(n)
	 */

	public boolean duplication(int[] numbers, int length, int[] duplication){
		
		//如果输入的数组为空,直接返回false
		if(numbers == null || length<=0)return false;
		
		//从头到尾扫描数组
		for(int i=0; i<length; i++){
			//如果数组不在1——n-1的范围内,直接返回false
			if(numbers[i]<0 || numbers[i]>=length)return false;
			//当数组中某个元素不等于其下标时,分为两种情况
			while(numbers[i]!=i){
				//如果这个元素与以这个元素值为下标的元素相等(元素本应该在的位置),则说明这个元素重复了
				if(numbers[i] == numbers[numbers[i]]){
					//把这个重复的元素存储在duplication[]数组中
					duplication[0] = numbers[i];
					return true;
				}else{         	//若不相等,即交换,把元素放到与下标对应的位置
					int temp = numbers[i];
					numbers[i] = numbers[temp];
					numbers[temp] = temp;
				}
			}
		}
		return false;
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_41163113/article/details/87863826