lintcode:Binary Search 二分查找

题目:

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1

样例

在数组 [1, 2, 3, 3, 4, 5, 10] 中二分查找3,返回2

挑战

如果数组中的整数个数超过了2^32,你的算法是否会出错?

解题:

利用二分查找,先判断左侧数据,满足条件则查找左侧,左侧不满足的时候在右侧找

当left>=right 时候表示没有找到返回 -1

当nums[left] ==target时候最左侧满足条件则找到了

再判断中位数是否满足条件

nums[median]==target and nums[median-1]!=target,return median

else:

对median的两侧进行判断

时间复杂度:O(logn)

Java程序:

class Solution {
    /**
     * @param nums: The integer array.
     * @param target: Target to find.
     * @return: The first position of target. Position starts from 0.
     */
    public int binarySearch(int[] nums, int target) {
        //write your code here
        if(nums.length==1 && nums[0]== target)
            return 0;
        int numsLen = nums.length;
        int index = binaryFind(nums,target,0,numsLen);
        return index;
    }
    public int binaryFind(int[] nums,int target,int left,int right){
        if(left>=right)
            return -1;
        if(nums[left]==target)
            return left;
        int median = (left+right)/2;
        if(target==nums[median] && target!=nums[median-1])
            return median;
        if(nums[median]>=target)
            return binaryFind(nums,target,left,median);
        else if(nums[median]<target)
            return binaryFind(nums,target,median+1,right);
        return -1;
    }
}
View Code

总耗时: 1504 ms

发现这里的运行时间,与我本地的网速关系很大。

直接线性查找,也是很简单的

    public int linFind(int[] nums ,int target){
        int numsLen = nums.length;
        for(int i=0;i<numsLen;i++)
            if(nums[i]==target)
                return i;
        return -1;
    }
View Code

总耗时: 1598 ms

耗时差不多的

当数组个数超过232 ,数组的下标是int型,已经越界,很大很大的时候median也会越界

Python程序:

class Solution:
    # @param nums: The integer array
    # @param target: Target number to find
    # @return the first position of target in nums, position start from 0 
    def binarySearch(self, nums, target):
        # write your code here
        return self.linFind(nums,target)
        # return self.binaryFind(nums,target,0,len(nums))
    def linFind(self,nums,target):
        for i in range(len(nums)):
            if nums[i]==target:
                return i
        return -1
        
    def binaryFind(self,nums,target,left,right):
        if left>=right:
            return -1
        if nums[left]==target:
            return left
        median = (left+right)/2
        if nums[median]==target and nums[median-1]!=target:
            return median
        if nums[median]>=target:
            return self.binaryFind(nums,target,left,median)
        elif nums[median]<target:
            return self.binaryFind(nums,target,median+1,right)
        else:
            return -1
View Code

两个运行时间,也差不多的。

总耗时: 314 ms

总耗时: 303 ms

原文地址:https://www.cnblogs.com/theskulls/p/4865917.html