找到最后一个不大于target的元素以及找到第一个不小于targ

2020-02-24  本文已影响0人  不知名小号

findLastNotBiggerThan,找到最后一个不大于target的元素,返回下标。

假设l, r是可能产生结果的区间。
l和r取中间mid

如果v[mid] <= target,则说明mid左边的数都是小于等于target的,而且mid又是这些数里最右边的,所以,相比于mid左边的数,mid更有可能是答案,故排除mid左边的数,令l = mid。
否则,v[mid] > target,我们要找的是不大于,所以mid不可能是解,并且mid右边的数都是大于v[mid]的,故将mid和mid右边的数都排除,即r = mid - 1

findFirstNotSmallThan,找到第一个不小于target的元素,返回下标

如果v[mid] >= target,那它右边的数都大于target,而且mid是这些数里最靠左的,所以排除了mid右边的元素,r = mid。
否则,v[mid] < target,那它左边的元素都是小于target的,mid本身不符合答案,mid左边的元素也不符合,所以l = mid + 1。

#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(s) memset(s, 0, sizeof(s))
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 7;
#define LOCAL

int findLastNotBiggerThan(std::vector<int> v, int target){
    int l = 0, r = v.size() - 1;
    while (l < r){
        int mid = (l + r + 1) / 2;
        if (v[mid] <= target){
            l = mid;
        }
        else{
            r = mid - 1;
        }
    }
    return l;
}
int findFirstNotSmallThan(std::vector<int> v, int target){
    int l = 0, r = v.size() - 1;
    while (l < r){
        int mid = (l + r) / 2;
        if (v[mid] >= target){
            r = mid;
        }
        else{
            l = mid + 1;
        }
    }
    return l;
}



int main(int argc, char * argv[]) 
{
 //   std::vector<int> v(1, 1, 2, 3, 5, 8);
    int a[] = {1, 1, 2, 3, 3, 4, 4, 4, 5, 6, 8, 10};
    vector<int> v(a, a + 12);
    for (int i = 0; i < v.size(); i++){
        cout << i << ": " << v[i] << " | ";
    }
    cout << endl;
    while (1){
        int t;
        cin >> t;
        cout << "findFirstNotSmallThan(v, t)" << endl;
        cout << findFirstNotSmallThan(v, t) << endl;
        cout << "findLasttNotBiggerThan(v, t)" << endl;
        cout << findLastNotBiggerThan(v, t) << endl;

    }
    return 0;
}
上一篇下一篇

猜你喜欢

热点阅读