Medium

Find First and Last Position of Element in Sorted ArrayC++

Full explanation · Time O(logn) · Space O(1)

// Time:  O(logn)
// Space: O(1)

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        const auto start = lower_bound(cbegin(nums), cend(nums), target);
        const auto end = upper_bound(cbegin(nums), cend(nums), target);
        if (start != cend(nums) && *start == target) {
            return {static_cast<int>(start - cbegin(nums)),
                    static_cast<int>(end - cbegin(nums) - 1)};
        }
        return {-1, -1};
    }
};

class Solution2 {
public:
    vector<int> searchRange(vector<int> &nums, int target) {
        const int begin = lower_bound(nums, target);
        const int end = upper_bound(nums, target);
        if (begin < size(nums) && nums[begin] == target) {
            return {begin, end - 1};
        }
        return {-1, -1};
    }

private:
    int lower_bound(const vector<int> &nums, int target) {
        int left = 0, right = size(nums) - 1;
        // Find min left s.t. A[left] >= target.
        while (left <= right) {
            const auto mid = left + (right - left) / 2;
            if (nums[mid] >= target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return left;  // or return right + 1
    }

    int upper_bound(const vector<int> &nums, int target) {
        int left = 0, right = size(nums) - 1;
        while (left <= right) {
            const auto mid = left + (right - left) / 2;
            if (nums[mid] > target) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return left;  // or return right + 1
    }
};

class Solution3 {
public:
    vector<int> searchRange(vector<int> &nums, int target) {
        const int begin = lower_bound(nums, target);
        const int end = upper_bound(nums, target);
        if (begin < size(nums) && nums[begin] == target) {
            return {begin, end - 1};
        }
        return {-1, -1};
    }

private:
    int lower_bound(const vector<int> &nums, int target) {
        int left = 0, right = size(nums);
        // Find min left s.t. A[left] >= target.
        while (left < right) {
            const auto mid = left + (right - left) / 2;
            if (nums[mid] >= target) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;  // or return right
    }

    int upper_bound(const vector<int> &nums, int target) {
        int left = 0, right = size(nums);
        // Find min left s.t. A[left] > target.
        while (left < right) {
            const auto mid = left + (right - left) / 2;
            if (nums[mid] > target) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;  // or return right
    }
};

class Solution4 {
public:
    vector<int> searchRange(vector<int> &nums, int target) {
        const int begin = lower_bound(nums, target);
        const int end = upper_bound(nums, target);
        if (begin < size(nums) && nums[begin] == target) {
            return {begin, end - 1};
        }
        return {-1, -1};
    }

private:
    int lower_bound(const vector<int> &nums, int target) {
        int left = -1, right = size(nums);
        // Find min left s.t. A[left] >= target.
        while (left + 1 < right) {
            const auto mid = left + (right - left) / 2;
            if (nums[mid] >= target) {
                right = mid;
            } else {
                left = mid;
            }
        }
        return left + 1;  // or return right
    }

    int upper_bound(const vector<int> &nums, int target) {
        int left = -1, right = size(nums);
        // Find min left s.t. A[left] > target.
        while (left + 1 < right) {
            const auto mid = left + (right - left) / 2;
            if (nums[mid] > target) {
                right = mid;
            } else {
                left = mid;
            }
        }
        return left + 1;  // or return right
    }
};