【剑指offer】Java数组中重复的数字

github地址:https://github.com/PLLLLLLL/offer-Java

    /**
     * 【题目描述】
     * 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。
     * 也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 
     * 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
     
     * 规律:题目中明确指出n个数字,其取值范围在0到n-1之间,所以可以认为
     * 如果都不相等,则数组下标总能找到和其一致的数字
     * 如果存在重复的,则某些数组下标应有一个以上的数字与之相一致
     * 所以我们通过找与下标一致的数字,如果当前下标中放得数字与下标不一致,则看该数字对应的下标中的数字是否和当前下标中的数字是否一致
     * 若一致,则输出,并找下一个重复数字
     * 若不一致,则交换两个下标对应的数字,并重复此过程
     * 这样,数字都落在与其一致的下标中,只有重复的数字,会落在其他与其不一致的(重复次数-1)下标中
     */
     
public class Solution {
    public static void duplicateInt3(int[] array) {
        if (array == null) {
            return;
        }
        // 存在重复数字,起码有两个以上的数字才可以
        int len = array.length;
        if (len < 2) {
            return;
        }
        
        // 数字中的数字范围在0到len-1之间,否则就认为是个错误的数组,不考虑重复数字问题
        for (int i = 0; i < len; i++) {
            if (array[i] < 0 || array[i] > len - 1) {
                return;
            }
        }
        
        // 比如 {2, 3, 1, 0, 2, 5, 3}
        // array[0] = 2,不一致,array[2] = 1, 不相等,则交换,得到 {1, 3, 2, 0, 2, 5, 3}
        // array[0] = 1,不一致,array[1] = 3, 不相等,则交换,得到 {3, 1, 2, 0, 2, 5, 3}
        // array[0] = 3,不一致,array[3] = 0, 不相等,则交换,得到 {0, 1, 2, 3, 2, 5, 3}
        // array[0] = 0,一致,现在下标0中存放了预期一致的数字,结束下标0的操作
        // array[1] = 1,一致,现在下标1中存放了预期一致的数字,结束下标1的操作
        // array[2] = 2,一致,现在下标2中存放了预期一致的数字,结束下标2的操作
        // array[3] = 3,一致,现在下标3中存放了预期一致的数字,结束下标3的操作
        // array[4] = 2,不一致,array[2] = 2,相等输出结果,无需交换,结束下标4的操作,此时 {0, 1, 2, 3, 2, 5, 3}
        // array[5] = 5,一致,现在下标5中存放了预期一致的数字,结束下标5的操作
        // array[6] = 3,不一致,array[3] = 3,相等输出结果,无需交换,结束下标4的操作,此时 {0, 1, 2, 3, 2, 5, 3}
        
        for (int i = 0; i < len; i++) {
            while (array[i] != i) {
                if (array[i] == array[array[i]]) {
                    System.out.print(array[i] + " ");
                    break;
                } else {
                    int temp = array[i];
                    array[i] = array[temp];
                    array[temp] = temp;
                }
            }
        }
        return;
    }
}

/**
  *或者如下
  */

public class Solution {
    // Parameters:
    //    numbers:     an array of integers
    //    length:      the length of array numbers
    //    duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
    //                  Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
    //    这里要特别注意~返回任意重复的一个,赋值duplication[0]
    // Return value:       true if the input is valid, and there are some duplications in the array number
    //                     otherwise false
    public boolean duplicate(int numbers[],int length,int [] duplication) {
        if (numbers == null || length<=0)
			return false;
		int tempVal = 0;
		for (int i=0;i<numbers.length;i++) {
			while (numbers[i]!=i) {
				if (numbers[i]==numbers[numbers[i]]) {
					//System.out.println(numbers[i]);
					duplication[0] = numbers[i];
					return true;
				}
				tempVal = numbers[i];
				numbers[i] = numbers[tempVal];
				numbers[tempVal] = tempVal;
			}
		}
		return false;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值