zoukankan      html  css  js  c++  java
  • 【Offer】[3-2] 【不修改数组找出重复的数字】

    题目描述

      在一个长度为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的。 请找出数组中任意一个重复的数字,但不能修改输入的数组。例如,如果输入长度为8的数组{2,3,5,4,3,2,6,7},那么对应的输出是重复的数字2或者3。
      

    思路分析

      题目中数组长度为 n+1 ,而数字的范围为1 ~ n,说明数组中必然存在重复的数字,可以利用类似于二分查找的方式,将1 ~ n 数字分成两半 一半是1 ~ m 另一半是 m+1 ~ n ,扫描数组,统计数组中数字出现在1 ~ m中的次数,如果该次数大于m则说明,重复的数字在1 ~ m之间,否则,改重复的数字就在m+1 ~ n之间 。

    Java代码

    public class Offer003_02 {
        public static void main(String[] args) {
            int[] arr = {1,9,4,4,3,2,6,7,7};
            int dupNum = Offer003_02.getDuplication(arr);
            System.out.println(dupNum);
        }
        
        public static int getDuplication(int[] arr) {
            return Solution1(arr);
        }
        
        /**
         * 由于题目中说明 数组长度为n+1,而数组中数字的范围为1~n, 这就说明数组中一定存在重复的数字
         * 将数字1 ~ n 切成两半:1 ~ m  、  m+1 ~n 
         * 可以判断 数组中数字在两个 范围中出现的次数,
         * 如果出现的次数大于 m , 则说明 重复的数字在1 ~ m 之间,否则,m+1 ~ n之间
         * 
         * 类似于二分查找的方法
         * 
         * @param arr
         * @return
         */
        private static int Solution1(int[]arr) {
            if(arr==null || arr.length<=0) {
                return -1;
            }
            int start = 1;
            int end = arr.length-1;
            while(end>=start) {
    //          int middle = ((end-start)>>1) + start;
                int middle = (end+start)>>1;
                int count = getCount(arr,start,middle);
                if(end==start) {
                    if(count > 1) {
                        return start;
                    }else {
                        break;
                    }
                }
                if(count > (middle-start)+1) {
                    end = middle;
                }else {
                    start = middle+1;
                }
            }
            return -1;
        }
        /**
         * 判断 arr  在start 和end 范围 内 有多少个元素
         * @param arr
         * @param start
         * @param end
         * @return
         */
        private static int getCount(int[] arr, int start, int end) {
            if(arr==null) {
                return 0;
            }
            int count = 0;
            for(int i=0;i< arr.length;i++) {
                if(arr[i]>=start&& arr[i]<=end) {
                    ++count;
                }
            }
            return count;
        }   
    }
    
    

    代码链接

    剑指Offer代码-Java

  • 相关阅读:
    第二阶段冲刺01
    客户端-服务器模式
    可用性和可修改性战术分析
    质量属性
    《架构漫谈》阅读笔记
    《软件需求模式》06
    《软件需求模式》05
    《软件需求模式》04
    《软件需求模式》03
    《软件需求模式》02
  • 原文地址:https://www.cnblogs.com/haoworld/p/boffer32-bu-xiu-gai-shu-zu-zhao-chu-zhong-fu-de-sh.html
Copyright © 2011-2022 走看看