Find the Duplicate Number

来源:互联网 发布:音乐基础知初级书教材 编辑:程序博客网 时间:2024/06/05 20:56

Description:

Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one…

问题描述

找出重复元素

解法一:

思路:

先来一种前面的链表查环入口的思路。。。。
将数组的下标和1到n每一个数一对一的映射起来。比如数组是213,则映射关系为0->2, 1->1, 2->3。
这个例子中有两个下标的序列,0->2->3。。。。
2131,则映射关系为0->2, {1,3}->1, 2->3。这样,我们推演的序列就一定会有环路了,这里下标的序列是0->2->3->1->1->1->1->…,而环的起点就是重复的数。
快指针映射两次,慢指针映射一次。。。。
思路同链表查环入口。。。

Code:

public class Solution {    public int findDuplicate(int[] nums) {        if(nums.length > 1){            int slow = nums[0];            int fast = nums[nums[0]];            while(slow != fast){                slow = nums[slow];                fast = nums[nums[fast]];            }            int start = 0;            while(start != slow){                start = nums[start];                slow = nums[slow];            }            return slow;        }        return -1;    }}

解法二:

思路:

二分法思路,根据抽屉原理。。。
用二分法先选取n/2,按照抽屉原理,整个数组中如果小于等于n/2的数的数量大于n/2,说明1到n/2这个区间是肯定有重复数字的。

Code:

public class Solution {    public int findDuplicate(int[] nums) {        int min = 0 , max = nums.length - 1;        while (min <= max){            int mid = min + (max - min) /2;            int cnt = 0;            //计算总数组中有多少个数小于等于中间数            for (int i = 0; i < nums.length; i++){                if (nums[i] <= mid){                    cnt++;                }            }            //如果小于等于中间数的数量大于中间数,说明前半部分必有重复            if (cnt > mid){                max = mid -1;            }            //否则后半部分必有重复            else{                min = mid + 1;            }        }        return min;    }}
0 0
原创粉丝点击