求数组中重复的数字

package com.banban.CeShi;

import java.util.*;

/**
 * @author :zhangpengzhan
 * @date :Created in 2019/3/29 16:52
 * @name :FindReNumber
 *
 *  找出数组中任意一个重复的数字:
 *      在长度为n数组里,元素范围均在0~n-1里,有些元素是重复的,但是不知道有几个重复了,找出
 *      任意一个重复的数字,例如输入:{2,3,1,0,2,5,3} 输出2或者3
 *
 *      方法一:排序加扫描
 *      方法二:哈希表
 *      方法三:从头到位依次扫描数组,当扫面到下标为i的数字,
 *          先比较这个数字m等不等于i下标
 *              等于:i++
 *              不等于:将数字m和数组下标为m的数字n比较
 *                  等于:找到与第一个重复数字
 *                  不等于:交换m和n,将m放到对应的下标去
 *          重复上述过程
 *              时间复杂o(n) 空间复杂o(1)
 *      方法四:不修改原数组,二分思想
 *            假定数组元素有八个,统计元素值为0~3的有几个,统计元素值为4~8的有几个,
 *            如果两个区间有一个区间的元素数量大于一半,说明该区间元素有重复,继续拆分该区间
 *            《改天实现吧》 
 */
public class FindReNumber {

    /**
     * 方法一:
     *  快排+扫描
     * @param num
     * @return
     */
    public static int findNumber1(int[] num){
        //算前检验
        if (num == null){
            return -1;
        }
        for (int i : num) {
            if (i<0||i>=num.length)
                return -1;
        }

        int[] sort = QuickSort(num, 0, num.length - 1);
        for (int i = 0; i < sort.length;i++) {
                int j = i+1;
                if (j == sort.length){
                    return -1;
                }
                if (sort[i] == sort[j]){
                   return sort[i];
                }
        }
        return -1;
    }

    /**
     *  快排算法
     * @return
     */
    private  static int[] QuickSort(int[] num,int start,int end){
        int i = start;
        int j = end;
        //定义基准数
        int temp = num[i];
        //判断
        if (start<end){
            //循环
            while (i<j){
                //从右往左比较
                while (i<j&&num[j]>=temp){
                    j--;
                }
                //找到比当前基数小的交换
                if (i<j){
                    //填坑
                    num[i] = num[j];
                    i++;
                }

                //从左往右找
                while (i<j&&num[i]<temp){
                    i++;
                }
                //找到比当前基数大的交换
                if (i<j){
                    //填坑
                    num[j] = num[i];
                    j--;
                }
            }
            //基数填到最后坑位
            num[i] = temp;
            QuickSort(num,start,i-1);
            QuickSort(num,i+1,end-1);
        }
        return num;
    }

    /**
     *  方法二:
     *
     * @param num
     * @return
     */
    public static int findNumber2(int[] num){
        //算前检验
        if (num == null){
            return -1;
        }
        for (int i : num) {
            if (i<0||i>=num.length)
                return -1;
        }
        Hashtable<Integer, Integer> hashtable = new Hashtable<>(num.length);
        for (int i = 0; i < num.length; i++) {
            if (!hashtable.containsKey(num[i])){
                hashtable.put(num[i],1);
            }else {
                hashtable.put(num[i],hashtable.get(num[i])+1);
            }
        }
        Set<Map.Entry<Integer, Integer>> set = hashtable.entrySet();
        for (Map.Entry<Integer, Integer> next : set) {
            if (next.getValue() >= 2) {
                return next.getKey();
            }
        }
        return -1;
    }

    /**
     *  方法三:
     *
     *
     * @param num
     * @return
     */
    public static int findNumber3(int[] num){
        //算前检验
        if (num == null){
            return -1;
        }
        for (int i : num) {
            if (i<0||i>=num.length)
                return -1;
        }

        for (int i = 0; i <num.length ; i++) {
            while (num[i] != i){
                if (num[i]!=num[num[i]]){
                     int temp;
                     temp = num[i];
                     num[i] = num[temp];
                     num[temp] = temp;
                }else {
                    return num[i];
                }
            }
        }
        return -1;
    }

//    /**
//     *  方法四:
//     *
//     * @param num
//     * @return
//     */
//    public static int findNumber4(int[] num){
//
//    }

    public static void main(String[] args) {
        int[] a =new  int[]{4,3,1,0,2,5,3};
        System.out.println(findNumber2(a));

    }

}

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页