34. Search for a Range

Given an array of integers sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].


这是一道典型的二分搜索问题,如果依次向后搜索时间复杂度就是O(n),但是题目要求O(log n)的复杂度.所以要使用二分搜索。

但是这里涉及到怎么区分左边的和右边的搜索。我的做法:

左边位置:比较mid=(i+j)/2处的值和target的大小,如果num[mid]>=target就把右边界移动到mid,否则移动左边界。循环结束条件是还剩下三个数的时候。此时从左往右依次比较是否和target相等,相等的就是左边界。

右边位置:比较mid=(i+j)/2处的值和target的大小,如果num[mid]<=target就把左边界移动到mid,否则移动右边界。循环结束条件是还剩下三个数的时候。此时从右往左依次比较是否和target相等,相等的就是右边界。

class Solution {
    public static int[] searchRange(int[] nums, int target) {
        int[] result = new int[2];
        
        if(nums.length==0){
            result[0] = -1;
            result[1] = -1;
            return result;
        }
        
        int start = 0;
        int end = nums.length - 1;
        while(start<end-1){
            int mid = (start+end)/2;
            if(nums[mid]>=target){                
                end = mid;
            }
            else
                start = mid;
        }
        if(nums[start]==target)
        	result[0]=start;
        else if(nums[(start+end)/2]==target)
        	result[0] = (start+end)/2;
        else if(nums[end]==target)
        	result[0] = end;
        else
        	return new int[]{-1,-1};
        
        start = 0;
        end = nums.length - 1;
        while(start<end-1){
            int mid = (start+end)/2;
            if(nums[mid]==target){
                result[1] = mid;
                start = mid;
            }
            else if(nums[mid]<target){
                start = mid;
            }
            else
                end = mid;
        }
        
        if(nums[end]==target)
        	result[1]=end;
        else if(nums[(start+end)/2]==target)
        	result[1] = (start+end)/2;
        else if(nums[start]==target)
        	result[1] = start;
        return result;
    }
}

但是其实这样做比较麻烦,参考方法:

不同之处主要是循环判断条件以及更新方式:左边位置的循环中i=mid+1导致可以自己结束循环。右边位置的循环中由于不能自己结束循环就把mid=(i+j)/2+1,也就是每次向右偏,那么最后也会自动终止循环。

public static int[] searchRange(int[] num, int target){
		int[] result = new int[2];
		if(num.length==0)
			return new int[]{-1,-1};
		int i=0, j = num.length;
		while(i<j){
			int mid = (i+j)/2;
			if(num[mid]>=target)
				j = mid;
			else 
				i = mid+1;
		}
		if(num[i]==target)
			result[0] = i;
		else 
			return new int[]{-1,-1};
		j = num.length;
		while(i<j){
			int mid = (i+j)/2+1;
			if(num[mid]<=target)
				i = mid;
			else
				j = mid-1;
		}
		if(num[j]==target)
			result[1] = j;
		return result;
	}

Java中三种数组初始化方法:
 //静态初始化数组:方法一  
        String cats[] = new String[] {  
                "Tom","Sam","Mimi"  
        };  
          
        //静态初始化数组:方法二  
        String dogs[] = {"Jimmy","Gougou","Doggy"};  
          
        //动态初始化数据  
        String books[] = new String[2];  
        books[0] = "Thinking in Java";  
        books[1] = "Effective Java";  




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值