Binary Search Problem Sets Part I

This wiki contains a couple of well-defined problems solved via Binary Search algorithm.

Search for a Range (61):

    int binSearch(vector<int> &array, int start, int end, int target){
        while(start <= end){
            int mid = (start+end)/2;
            if(array[mid] == target){
                return mid;
            } else if(array[mid] < target){
                start = mid+1;
            } else {
                end = mid-1;
            }
        }
        return -1;
    }


    int binSearchStart(vector<int> &array, int start, int end, int target){
        while(start <= end){
            if(start==end && array[start]==target){
                return start;
            } else if(start==end-1 && array[start]==target){
                return start;
            } else if(start==end-1 && array[end]==target){
                return end;
            } else if(start==end || start==end-1){
                return -1;
            }

            int mid = (start+end)/2;
            if(array[mid] == target){
                end = mid;
            } else if(array[mid] < target){
                start = mid+1;
            } else {
                end = mid-1;
            }
        }
        return -1;
    }

    int binSearchEnd(vector<int> &array, int start, int end, int target){
        while(start <= end){
            if(start==end && array[end]==target){
                return end;
            } else if(start==end-1 && array[end]==target){
                return end;
            } else if(start==end-1 && array[start]==target){
                return start;
            } else if(start==end || start==end-1){
                return -1;
            }

            int mid = (start+end)/2;
            if(array[mid] == target){
                start = mid;
            } else if(array[mid] < target){
                start = mid+1;
            } else {
                end = mid-1;
            }
        }
        return -1;
    }

    vector<int> searchRange(vector<int> &a, int target) {
        // write your code here
        // int index = binSearch(a,0,a.size()-1,target);
        // if(index == -1){
        //     return {-1,-1};
        // }
        // int startIndex=index, endIndex=index;
        // while(startIndex>0 && a[startIndex-1]==target){
        //     startIndex--;
        // }
        // while(endIndex<a.size()-1 && a[endIndex+1]==target){
        //     endIndex++;
        // }
        // return {startIndex, endIndex};
        int startIndex = binSearchStart(a, 0, a.size()-1, target);
        int endIndex = binSearchEnd(a, 0, a.size()-1, target);
        return {startIndex, endIndex};
    }

Search in Rotated Sorted Array (62):

    int findRotatedIndex(vector<int> &array, int start, int end){
        if(array[start] <= array[end]){
            return start;
        }
        while(start <= end){
            if(start==end){
                return start;
            } if(start==end-1 && array[start]<=array[end]){
                return start;
            } else if(start==end || start==end-1){
                return end;
            }

            int mid = (start+end)/2;
            if(array[start] > array[mid]){
                end = mid;
            } else {
                start = mid;
            }
        }
        return -1;
    }

    int binSearch(vector<int> &array, int start, int end, int target){
        while(start <= end){
            int mid = (start+end)/2;
            if(array[mid] == target){
                return mid;
            } else if(array[mid] < target){
                start = mid+1;
            } else {
                end = mid-1;
            }
        }
        return -1;
    }

    int search(vector<int> &a, int target) {
        // write your code here
        if(a.size()==0){
            return -1;
        }
        int rotatedIndex = findRotatedIndex(a, 0, a.size()-1);
        // cout<<"r:"<<rotatedIndex<<endl;
        if(target > a[a.size()-1]){
            return binSearch(a, 0, rotatedIndex-1, target);
        } else {
            return binSearch(a, rotatedIndex, a.size()-1, target);
        }
    }

First Bad Version (74):

    int findBinSearch(long long int start, long long int end){
        // if(!SVNRepo::isBadVersion(end)){
        //     return end;
        // }
        while(start <= end){
            // cout<<"start:"<<start<<" end:"<<end<<endl;
            if(start==end){
                if(SVNRepo::isBadVersion(start)){
                    return start;
                }
                return -1;
            } else if(start==end-1){
                if(SVNRepo::isBadVersion(start)){
                    return start;
                } else if(SVNRepo::isBadVersion(end)){
                    return end;
                }
                return -1;
            }

            // if(!SVNRepo::isBadVersion(end)){
            //     return end;
            // }
            long long int mid = (start+end)/2;
            if(SVNRepo::isBadVersion(mid)){
                end = mid;
            } else {
                start = mid;
            }
        }
        return -1;
    }

    int findFirstBadVersion(int n) {
        // write your code 
        return findBinSearch(1, n);
    }

Search in Rotated Sorted Array II (63):

    int findRotatedIndex(vector<int> &array, int start, int end){
        while(start <= end){
            if(array[start] < array[end]){
                return start;
            } else if(start==end){
                return start;
            } else if(start == end-1){
                if(array[start] <= array[end]){
                    return start;
                }
                return end;
            } else if(array[start] == array[end]){
                start++;
                end--;
                continue;
            }

            int mid = (start+end)/2;
            if(array[start] == array[mid]){
                start = mid;
            } else if(array[start] < array[mid]){
                start = mid;
            } else {
                end = mid;
            }
        }

        return -1;
    }

    int binSearch(vector<int> &array,int start, int end, int target){
        while(start <= end){
            int mid = (start+end)/2;
            if(array[mid] == target){
                return mid;
            } else if(array[mid] < target){
                start = mid+1;
            } else {
                end = mid-1;
            }
        }
        return -1;
    }

    bool search(vector<int> &a, int target) {
        // write your code here
        int rotatedIndex = findRotatedIndex(a, 0, a.size()-1);\
        // cout<<"rotated index:"<<rotatedIndex<<endl;
        if(rotatedIndex== -1){
            return false;
        }
        if(target > a[a.size()-1]){
            int index = binSearch(a, 0, rotatedIndex-1, target);
            if (index==-1){
                return false;
            }
            return true;
        } else {
            int index = binSearch(a, rotatedIndex, a.size()-1, target);
            if(index== -1){
                return false;
            }
            return true;
        }
    }

Count of Smaller Number (248):

    int findLowestUpper(vector<int> &array, int target){
        int start=0, end=array.size()-1;
        if(array.size()==0){
            return 0;
        }
        if(array[array.size()-1]<target){
            return array.size();
        }
        while(start <= end){
            if(start==end){
                return start;
            } else if(start==end-1 && array[start]>=target){
                return start;
            } else if(start==end-1){
                return end;
            }

            int mid = (start+end)/2;
            if(array[mid] < target){
                start = mid+1;
            } else {
                end = mid;
            }
        }
        return 0;
    }

    vector<int> countOfSmallerNumber(vector<int> &a, vector<int> &queries) {
        // write your code here
        sort(a.begin(), a.end());
        vector<int> result;
        for(int i=0;i<queries.size();i++){
            int index = findLowestUpper(a, queries[i]);
            result.push_back(index);
        }
        return result;
    }

Copy Books (437):

    bool isPossibletoComplete(vector<int> &array, int persons, int time){
        int remTime = time;
        int remPersons = persons;
        for(int i=0;i<array.size();i++){
            while(remTime<array[i] && remPersons>0){
                remTime = time;
                remPersons--;
            }
            if(remTime<array[i] || remPersons<=0){
                return false;
            }
            remTime -= array[i];
        }
        return true;
    }

    int binSearchPossibleTime(vector<int> &array, int persons){
        int start=1, end=0;
        for(int i=0;i<array.size();i++){
            end += array[i];
        }
        // what if it's not possible even with the largest number?

        while(start <= end){
            if(start == end){
                return start;
            } else if(start==end-1){
                if(isPossibletoComplete(array, persons, start)){
                    return start;
                }
                return end;
            }
            int mid = (start+end)/2;
            if(isPossibletoComplete(array, persons, mid)){
                end = mid;
            } else {
                start = mid;
            }
        }
        return 0;// not possible
    }
    int copyBooks(vector<int> &pages, int k) {
        // write your code here
        // for(int i=0;i<=10;i++){
        //     cout<<"i:"<<i<<", "<<isPossibletoComplete(pages,k,i)<<endl;
        // }
        return binSearchPossibleTime(pages, k);
    }

How Many Problem Can I Accept (937):

    long long canAccept(long long n, int k) {
        // Write your code here
        long long int value = sqrt((2 * (long long int)n) / (long long int)k + 0.25 ) - 0.5;
        return value;
    }

Missing Element in Sorted Array (3661):

    int binSearchLowerBoundDiff(vector<int> &array, int diffIndex){
        int start=0, end=array.size()-1;
        if(array.size()==0){
            return -1;
        }
        if(array[(array.size()-1)]-(array.size()-1)-array[0] < diffIndex){
            return array.size()-1;
        }
        while(start <= end){
            if(start==end){
                return start;
            } else if(start == end-1){
                if(array[end]-end-array[0] < diffIndex){
                    return end;
                }
                return start;
            }

            int mid = (start+end)/2;
            if(array[mid]-mid-array[0] < diffIndex){
                start = mid;
            } else {
                end = mid;
            }
        }
        return -1;// only in trivial case
    }

    int missingElement(vector<int> &nums, int k) {
        // write your code here
        // cout<<"k:"<<k<<endl;
        // for(int i=0;i<nums.size();i++){
        //     cout<<nums[i]<<",";
        // }
        // cout<<endl;
        int index = binSearchLowerBoundDiff(nums, k);
        // cout<<"index:"<<index<<endl;
        if(index < 0){
            return k;
        }
        return nums[index]+(k-(nums[index]-nums[0]-index));
    }

Count Pairs in Two Arrays (3733):

    int binSearchGreaterThan(vector<int> &array, int startIndex, int endIndex, int target){
        int start=startIndex, end=endIndex;
        while(start <= end){
            if(start==end){
                if(array[start] >= target){
                    return start;
                }
                return -1;
            } else if(start==end-1){
                if(array[start] >= target){
                    return start;
                } else if(array[end] >= target){
                    return end;
                } else {
                    return -1;
                }
            }
            int mid = (start+end)/2;
            if(array[mid] >= target){
                end = mid;
            } else {
                start = mid;
            }
        }
        return -1;
    }

    long long countPairs(vector<int> &nums1, vector<int> &nums2) {
        // write your code here
        vector<int> array;
        for(int i=0;i<nums1.size();i++){
            array.push_back(nums1[i]-nums2[i]);
        }
        sort(array.begin(), array.end());
        
        // cout<<"sorted diff: ";
        // for(int i=0;i<array.size();i++){
        //     cout<<"("<<i<<":"<<array[i]<<") ";
        // }
        // cout<<endl;

        long long int count = 0;
        for(int i=0;i<array.size();i++){
            int targetVal = array[i]<0?(-array[i]+1):1;
            int index = binSearchGreaterThan(array, i+1, array.size()-1, targetVal);
            // cout<<"i:"<<i<<" targetVal:"<<targetVal<<" index:"<<index<<endl;
            if(index != -1){
                count += (array.size()-index);
            }
        }
        return count;
    }

Single Element in a Sorted Array (1183):

    int binSearchNonDuplicate(vector<int> &array){
        if(array.size()%2==0){
            return -1;
        }
        int start=0, end=array.size()-1;
        while(start <= end){
            if(start<=end && array[start]==array[start+1]){
                start++;
            }
            if(end<array.size()-1 && array[end]==array[end+1]){
                end++;
            }
            if(start==0){
                return start;
            }
            if(start>0 && array[start]!=array[start-1]){
                return start;
            }
            if(end>0 && array[end]!=array[end-1]){
                return end;
            }

            if(start==end){
                return start;
            } else if(start==end-1){
                if(start>0 && array[start]==array[start-1]){
                    return end;
                }
                return start;
            } else if(start==end-2){
                if(array[start]==array[start+1]){
                    return end;
                }
                return start;
            }

            int mid = (start+end)/2;
            // cout<<"start:"<<start<<" end:"<<end<<" mid:"<<mid<<endl;
            if(mid<array.size() && array[mid]==array[mid+1]){
                mid++;
            }
            // cout<<"start:"<<start<<" end:"<<end<<" mid2:"<<mid<<endl;
            if((start-mid)%2==0){
                start = mid;
            } else {
                end = mid;
            }
            // cout<<"start:"<<start<<" end:"<<end<<endl;
        }
        return -1;
    }
    int singleNonDuplicate(vector<int> &nums) {
        // write your code here
        int index = binSearchNonDuplicate(nums);
        // cout<<"index:"<<index<<endl;
        if(index>=0){
            return nums[index];
        }
        return -1;
    }

Build a temple (1669):

    bool isPossibleConstruct(int m, vector<int> &woods, int len){
        int remWoods = m;
        // cout<<"checking ispossible for val:"<<len<<" with sticks:"<<m<<endl;
        for(int i=0;i<woods.size();i++){
            remWoods -= woods[i]/len;
            // cout<<"i:"<<i<<" rem:"<<remWoods<<endl;
            if(remWoods <= 0){
                return true;
            }
        }
        return remWoods<=0?true:false;
    }

    int binSearch(int m, vector<int> &woods){
        int start=1, end=woods[woods.size()-1];
        while(start<=end){
            if(start==end){
                if(isPossibleConstruct(m, woods, start)){
                    return start;
                }
                return -1;
            } else if(start == end-1){
                if(isPossibleConstruct(m, woods, end)){
                    return end;
                }
                if(isPossibleConstruct(m, woods, start)){
                    return start;
                }
                return -1;
            }

            int mid = (start+end)/2;
            // cout<<"start:"<<start<<" end:"<<end<<" mid:"<<mid<<endl;
            if(!isPossibleConstruct(m, woods, mid)){
                end = mid;
            } else {
                start = mid;
            }
        }
        return -1;
    }

    int buildTemple(int m, vector<int> &woods) {
        // write your code here.
        sort(woods.begin(), woods.end());
        int len = binSearch(m, woods);
        return len;
    }

Find Minimum in Rotated Sorted Array II (160):

    int binSearchMinRotated(vector<int> &nums){
        int start=0, end=nums.size()-1;
        while(start <= end){
            if(start==end){
                return start;
            } else if(start==end-1){
                if(nums[start] <= nums[end]){
                    return start;
                }
                return end;
            }
            if(nums[start] < nums[end]){
                return start;
            }
            int mid = (start+end)/2;
            // cout<<"start:"<<start<<" end:"<<end<<" mid:"<<mid<<endl;
            if(nums[start]==nums[mid]){
                start++;
                // end--;
            } else if(nums[end]==nums[mid]){
                end--;
            } else if(nums[start] > nums[mid]){
                end = mid;
            } else {
                start = mid; 
            }
        }
        return -1;
    }
    int findMin(vector<int> &nums) {
        // write your code here
        int index = binSearchMinRotated(nums);
        if(index >= 0){
            return nums[index];
        }
        return -1;
    }

Kth Smallest Subarray Sum (3736):

    int kthSmallestSubarraySum(vector<int> &nums, int k) {
        // write your code here

        priority_queue<int, vector<int>> heap;
        for(int i=0;i<nums.size();i++){
            int sum = 0;
            for(int j=i;j<nums.size();j++){
                sum += nums[j];
                heap.push(sum);
            }
        }

        while(heap.size()>k){
            // cout<<heap.top()<<",";
            heap.pop();
        }
        return heap.top();
    }

Find K Closest Elements (460):

    int binSearchUpperBoundIndex(vector<int> &array, int target){
        int start=0, end=array.size()-1;
        while(start <= end){
            if(start==end){
                return start;
            } else if(start==end-1){
                if(array[start] >= target){
                    return start;
                }
                return end;
            }

            int mid = (start+end)/2;
            // cout<<"start:"<<start<<" end:"<<end<<" mid:"<<mid<<endl;
            if(array[mid] == target){
                return mid;
            } else if(array[mid] < target){
                start = mid;
            } else {
                end = mid;
            }
        }
        return -1;
    }

    vector<int> kClosestNumbers(vector<int> &a, int target, int k) {
        // write your code here
        int index = binSearchUpperBoundIndex(a, target);
        vector<int> result;
        if(index == -1){
            return result;
        }
        // cout<<"index:"<<index<<endl;

        int i=index-1,j=i+1;
        for(int ii=0;ii<k;ii++){
            if(i<0 && j>=a.size()){
                break;
            } else if(i<0){
                result.push_back(a[j++]);
            } else if(j>=a.size()){
                result.push_back(a[i--]);
            } else if(abs(a[i]-target) <= abs(a[j]-target)){
                result.push_back(a[i--]);
            } else {
                result.push_back(a[j++]);
            }
        }
        return result;
    }

H-Index II (1303):

    int binSearch(vector<int> &citations){
        int start=0, end=citations.size()-1;
        while(start <= end){
            if(start == end){
                if(citations[start] >= citations.size()-start){
                    return start;
                }
                return -1;
            } else if(start == end-1){
                if(citations[start] >= citations.size()-start){
                    return start;
                }
                if(citations[end] >= citations.size()-end){
                    return end;
                }
                return -1;
            }

            int mid = start + (end-start)/2;
            // cout<<"start:"<<start<<" end:"<<end<<" mid:"<<mid<<endl;
            if(citations[mid] >= citations.size()-mid){
                end = mid;
            } else {
                start = mid;
            }
        }
        return -1;
    }

    int hIndex(vector<int> &citations) {
        // write your code here
        // sort(citations.begin(), citations.end());

        // Binary search to find the smallest index where citations[i] >= n - i
        int index = binSearch(citations);
        // cout<<"index:"<<index<<endl;
        if(index < 0){
            return 0;
        }
        return citations.size()-index;
    }

Kth Smallest Number in Sorted Matrix (401):

    int kthSmallest(vector<vector<int>> &matrix, int k) {
        // write your code here

        priority_queue<int, vector<int>> heap;
        for(int i=0;i<matrix.size();i++){
            if(i>=k){
                break;
            }
            for(int j=0;j<matrix[i].size();j++){
                if(j>=k){
                    break;
                }
                heap.push(matrix[i][j]);
                if(heap.size() > k){
                    heap.pop();
                }
            }
        }
        return heap.top();
    }

Find Words (194):

    bool isSubsequence(string &str, string &target){
        int tgtIndex = 0;
        for(int i=0;i<str.size();i++){
            if(tgtIndex<target.size() && target.at(tgtIndex)==str.at(i)){
                tgtIndex++;
            }
        }
        return tgtIndex==target.size();
    }

    vector<string> findWords(string &str, vector<string> &dict) {
        // write your code here.
        vector<string> result;
        for(string &tgt : dict){
            if(isSubsequence(str, tgt)){
                result.push_back(tgt);
            }
        }
        return result;
    }
Written on January 19, 2025