31.剑指Offer之数组中重复的数字

1题目描述:

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

2.解题思路

  思路采用非暴力查找和不消耗额外空间的算法:数组重排。把原数组重新排列为一个元素和对应下标值相同的数组。该算法看起来是两层循环,但是每个数字最多进行两次交换就会找到属于自己的位置,因为总的时间复杂度还是O(n),不需要额外内存。

  以{2,3,1,0,2,5,3}为例:

  • 0(序号)和2(0号值)不相等,并且2(序号)和1(2号值)不相等,则交换位置,数组变为:{1,3,2,0,2,5,3};

  • 0(序号)和1(0号值)仍然不相等,并且1(序号)和3(1号值)不相等,则交换位置,数组变为:{3,1,2,0,2,5,3};

  • 0(序号)和3(0号值)仍然不相等,并且3(序号)和0(3号值)不相等,则交换位置,数组变为:{0,1,2,3,2,5,3};

  • 0(序号)和0(0号值)相等,遍历下一个元素;

  • 1(序号)和1(1号值)相等,遍历下一个元素;

  • 2(序号)和2(2号值)相等,遍历下一个元素;

  • 3(序号)和3(3号值)相等,遍历下一个元素;

  • 4(序号)和2(4号值)不相等,但是2(序号)和2(4号值)相等,则找到了第一个重复的元素。

3.编程实现(Java):

public class duplicate_31 {
    public boolean duplicate(int numbers[], int length, int[] duplication) {
        if (numbers == null || length < 1)
            return false;
        for (int i = 0; i < length; i++) {
            while (numbers[i] != i) {
                if (numbers[numbers[i]] == numbers[i]) {
                    duplication[0] = numbers[i];
                    return true;
                } else {
//必须先numbers[numbers[i]],如果不是,先numbers[i]会改变numbers[numbers[i]]里面的序号
                    int temp = numbers[numbers[i]];
                    numbers[numbers[i]] = numbers[i];
                    //将numbers[i]弄到和它序号相对应的位置
                    numbers[i] = temp;
                }
            }
        }
        return false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值