leetcode做题总结,题目Search for a Range 2012/03/02

本文介绍了一种在有序列表中查找指定目标值首次和末次出现位置的算法,通过二分查找优化时间复杂度。

题目是求出一个有序列表有多个重复的target的第一个和最后一个的index,我的做法是先用二分找出其中一个target,然后向两边推进找出最前和最后的位置。


 public int[] searchRange(int[] A, int target) {
        int[] res ={-1,-1};
        if(A.length==0)return res;
        int i=0, j=A.length-1, p=-1;
        while(i<=j){
            int m=(i+j)/2;
            if(A[m]==target){
                p=m;
                break;
            } 
            if(A[m]<target) i=m+1;
            else j=m-1;
        }
        if(p==-1)return res;
        i=p;
        j=p;
        while(i>=0&&A[i]==target){
            i--;
        }
        while(j<=A.length-1&&A[j]==target){
            j++;
        }
        res[0]=i+1;
        res[1]=j-1;
        return res;
    }

Update 2015/08/22: 上面的解法不对,不是logn,正确的解法是使用两次二分法找到对应的左、右节点。


public class Solution {
    /** 
     *@param A : an integer sorted array
     *@param target :  an integer to be inserted
     *return : a list of length 2, [index1, index2]
     */
    public int search(ArrayList<Integer> A, int start, int end, boolean left, int target){
        while (start <= end){
            int mid = (start + end) / 2;
            if (A.get(mid) == target){
                if (left){
                    if (mid == 0 || A.get(mid) > A.get(mid - 1)){
                        return mid;
                    } else {
                        end = mid - 1;
                    }
                } else {
                    if (mid == A.size() - 1 || A.get(mid) < A.get(mid + 1)){
                        return mid;
                    } else {
                        start = mid+1;
                    }
                }
            } else if (A.get(mid) < target){
                start = mid+1;
            } else {
                end = mid-1;
            }
        }
        return -1;
        
    }
    
    public ArrayList<Integer> searchRange(ArrayList<Integer> A, int target) {
        // write your code here
        ArrayList<Integer> res = new ArrayList<Integer>();
        res.add(search(A, 0, A.size() - 1, true, target));
        res.add(search(A, 0, A.size() - 1, false, target));
        return res;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值