发表于: 2018-03-24 22:45:57

1 567


今天完成的事情:

1. 剑指offer 面试题3.2

明天计划的事情

1. 剑指offer 面试题4

2. 看基础

3. 代码还是不能落下,springboot学习1-2个小时

遇到的问题:


收获:

找出数组中重复的数字 

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

现在的条件是 空间复杂度为O(1) ,所以需要用时间换空间。

/**
* @description:  通过二分法查找重复数字,每次扫描都是统计全部数组中,符合范围的数字
* 8个位置上出现数字的范围为1-7,那么一定至少有一个数字有重复
* 在值为 1-4 上 ,如果每个数字重复的次数超过4次,那重复的数字一定在1-4之间。要是在4次之内,就一定在5-7之间。
* @param a
* @return: java.util.Map
* @author: Administrator
* @date: 2018-03-24  下午 2:32
*/

public static Integer problem3_1(Integer[] a) throws Exception {
//先判断数组是否为空
   if( a == null ||a.length == 0){
        throw new Exception("数组为空");
   }
   if( a == null ||a.length == 0){
       throw new Exception("数组为空");
   }
   for(int i= 0;i<a.length;i++){

   //判断这个数是否为空,为空就不进行比较
       if(a[i] == null ){
              continue;
       }

        //判断这个数是否符合算法规则
     if(a[i] > a.length-1 || a[i]<1){
           throw new Exception("数组创建异常");
       }
    }
   Integer start = 1;
   Integer end = a.length-1;
   while (end >= start){

   //获取中间大小的数值,例如1-74距离13位数,4-73位数,所以取4,而不是取数组位置上的中间位。
  Integer middle = (end+start)>>1;
   //统计 大小为start -- middle 之间的数字出现的次数
  int count = count(a,start,middle);
       //当统计到 二分法 最右边的时候,即不断的二分直到只有一个数字的时候无法二分了
  if(end.equals(start)){
      if (count>1){
            return start;
      }
      else {

         break;

       }

   }

       //count统计的数量大于每种数字假设只出现一次的数量,即假设1-4每个数字只出现一次,则本应只有4个数,但统计
    //1-4的数字却有5个,则对这些数字进行二分法后再次查找
    if(count>(middle-start + 1) ){
          end = middle;
      }
      //如果二分法的左边数字个数正常,那么重复的数字在左边一定有,右边也可能有,例如:1-4之间的数字没有1
       //而是有两个2.
       else {
          start = middle+1;
       }

     }

   return -1;
}


/**
* @description:  统计整个数组中1-4之间的数字出现的次数
* @param a
* @param start
* @param middle
* @return: int
* @author: Administrator
* @date: 2018-03-24  下午 3:08
*/

private static int count(Integer[] a, Integer start, Integer middle){
   int count = 0;
   for( int i =0;i<a.length;i++ ){
      if( a[i]<= middle&&a[i]>=start ){
           count++;
       }
   }
   return count;
}






返回列表 返回列表
评论

    分享到