zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    Java并发编程
    Git
    Spring Boot
    IDEA工具
    Java基础
    数据库架构
    设计模式
    网络基础
    管理知识
    linux安装数据库mysql
  • 原文地址:https://www.cnblogs.com/zy230530/p/6736033.html
Copyright © 2011-2022 走看看