LeetCode--二分查找相关算法

-(1)有一个升序排列的非负数组,要求利用o(logn)的时间复杂度找到数组中确定数字target的第一次出现的位置下标和最后一次出现的位置下标,如果不存在该target返回[-1,-1]

解决方案:本题是考察二分查找算法,通过两次二分查找算法找到target的起始下标和终止下标,放在一个数组中返回

public int[] findFirstAndLastIndex(int[] nums,int target){

  int[] res = new int[]{-1,-1};

  if(nums==null || nums.length<=1||target<0) 

    return res;

res[0]=findFirst(nums,target);

res[1]=findLast(nums,target);

return res;

}

public int findFirst(int[] nums,int target){

   int idx=-1;

   int start=0,end=nums.length-1,mid=0;

    while(start<=end){

          mid=start+(end-start)/2;

          if(nums[mid]>=target)

              end=mid-1;

          else

              start=mid+1;

         if(nums[mid]==target)

              idx=mid;

         }

        return idx;

}

public int findLast(int[] nums,int target){

   int idx=-1;

   int start=0,end=nums.length-1,mid=0;

    while(start<=end){

          mid=start+(end-start)/2;

          if(nums[mid]<=target)

              start=mid+1;

          else

              end=mid-1;

         if(nums[mid]==target)

              idx=mid;

         }

        return idx;

}

(2) 每一个app开发出来后,我们需要定期的对其进行更新(不管是升级还是修改bug),假设app当前已有n个版本,如果某一个版本出现错误,那么从这个版本开始后面的版本全部会出错,要求我们找出第一个出现错误的版本

解决方案:还是二分查找,当我们当前的mid对于的版本是错误版本(假设给定一个函数isError(viersion),true为错误版本,flase为正确版本),我们就往mid的左半部分找到初始错误版本,否则,就往mid右半部分找到初始错误版本

public int findFirstErrorVersion(int n){

int start=1,end=n,mid=1;

while(start<end){
     mid=start+(end-start)/2;//为什么不是mid=(start+end)/2

     if(!isError(mid))

         start=mid+1;

    else

         end=mid;

    }

    return start;

}

接下来,我解释一下上面的一个问题,为什么不能写成mid=(start+end)/2,因为,start,end均为整型数据,int型数据的最大值为2147483647,假如这里n=Integer.MAX_VALUE ,start=Integer.MAX_VALUE-1,end=Integer.MAX_VALUE,那么此时,(start+end)必须超过整型数据的返回,自然会出现问题,所以,一般情况下,最好还是写成start+(end-start)/2形式,何乐而不为呢?

补加:

Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.

 private int solveNLogN(int s, int[] nums) {
        int[] sums = new int[nums.length + 1];
        for (int i = 1; i < sums.length; i++) sums[i] = sums[i - 1] + nums[i - 1];
        int minLen = Integer.MAX_VALUE;
        for (int i = 0; i < sums.length; i++) {
            int end = binarySearch(i + 1, sums.length - 1, sums[i] + s, sums);
            if (end == sums.length) break;
            if (end - i < minLen) minLen = end - i;
        }
        return minLen == Integer.MAX_VALUE ? 0 : minLen;
    }
    
    private int binarySearch(int lo, int hi, int key, int[] sums) {
        while (lo <= hi) {
           int mid = (lo + hi) / 2;
           if (sums[mid] >= key){
               hi = mid - 1;
           } else {
               lo = mid + 1;
           }
        }
        return lo;
    }
}

 

posted @ 2017-04-19 21:37  卑微的蜗牛  阅读(528)  评论(0编辑  收藏  举报