算法设计周记(七)--查找

问题导入


给定一个升序排列的数组以及一个目标整数,要求返回该数在数组中的角标范围,若不存在则返回[-1,-1]. 要求算法的时间复杂度不超过O(logN).

一般求解

先考虑数组可能为空的特殊状况,排除之后将返回值初始化为给定数组的范围,逐渐向内逼近即可.
class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> rtn(2, -1);
        int begin = 0, end = nums.size()-1;
        if (end < 0) return rtn;
        while (nums[begin] < target) begin++;
        while (nums[end] > target) end--;
        if (begin > end) return rtn;
        rtn.clear();
        rtn.push_back(begin);
        rtn.push_back(end);
        return rtn;
    }
};
这种算法虽然进行了两次循环,但真正循环的次数一定是小于等于数组长度的,所以满足题目对时间复杂度的要求.然而查找目标值的方法是遍历,效率比较低下.

查找优化

在已完成排序的数组中进行对特定值的查找,二分法无疑是最为优秀的.这里fork到一份二分递归查找的代码,以供学习参考.
class Solution {
public:
    typedef vector<int> VI;
    void recur(VI & v,int T,int i,int j,VI & ans) {
        if ( i>j ) return;
        if ( i==j ) {
            if ( v[i]==T ) {
                if ( ans[0]==-1 || i<ans[0] ) ans[0]=i;
                if ( ans[1]==-1 || i>ans[1] ) ans[1]=i;
            }
            return;
        }
        int mid(i+(j-i)/2);
        if ( v[mid]<T ) recur(v,T,mid+1,j,ans);
        else if ( v[mid]>T ) recur(v,T,i,mid-1,ans);
        else {
            recur(v,T,i,mid,ans);
            recur(v,T,mid+1,j,ans);
        }
    }
    vector<int> searchRange(vector<int>& v, int T) {
        VI ans(2,-1);
        recur(v,T,0,v.size()-1,ans);
        return ans;
    }
};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值