Lintcode 二分查找

14 · 二分查找
算法
简单
通过率39%
 
描述

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

样例

样例 1:

输入:

数组 = [1,4,4,5,7,7,8,9,9,10]
target = 1

输出:

0

解释:

第一次出现在第0个位置。

样例 2:

输入:

数组 = [1, 2, 3, 3, 4, 5, 10]
target = 3

输出:

2

解释:

第一次出现在第2个位置

样例 3:

输入:

数组 = [1, 2, 3, 3, 4, 5, 10]
target = 6

输出:

-1

解释:

没有出现过6, 返回-1

挑战

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

 

题解:

mid是 start 和 end中间的数字

让start 和 end保持2个数字或以上的间隔

如果mid的值和target相等, 那么mid的值赋给end, 让循环继续

直至start和end的间距小于等于2, 那么就可以直接锁定数据的范围

target的位置就是start 或者 end, 或者不存在 返回-1

package lint;

import org.junit.Assert;
import org.junit.Test;

public class BinarySearch2 {
    public int binarySearch(int[] nums, int target) {
        int start = 0;
        int end = nums.length-1;
        int mid = -1;
        while(start+1<end){
            mid = start + (end-start)/2;
            System.out.println("in while : mid:"+mid+ ", start:"+start + ", end:"+end);
            if(nums[mid]>=target){
                end = mid;
            }else if(nums[mid]<target){
                start = mid;
            }
        }
        System.out.println("out while : mid:"+mid+ ", start:"+start + ", end:"+end);
        if(nums[start]==target){
            return start;
        }else if(nums[end]==target){
            return end;
        }
        return -1;
    }

    @Test
    public void test1() {
        Assert.assertEquals(3, new BinarySearch2().binarySearch(new int[]{3,4,5,8,8,8,8,10,13,14}, 8));
    }
    @Test
    public void test2() {
        Assert.assertEquals(2, new BinarySearch2().binarySearch(new int[]{1, 2 ,3, 4}, 3));
    }

    @Test
    public void test3(){
        Assert.assertEquals(3, new BinarySearch2().binarySearch(new int[]{1, 2 ,3, 4}, 4));
    }

    @Test
    public void test4(){
        Assert.assertEquals(3, new BinarySearch2().binarySearch(new int[]{1, 2 ,3, 4,4, 4, 5}, 4));
    }
}

 

posted @ 2022-07-14 07:24  Appinn  阅读(26)  评论(0编辑  收藏  举报