pranay_teja
11/8/2018 - 10:03 AM

FindKClosestElements-BinarySearch

#include<bits/stdc++.h>
using namespace std;

//  a[i]  0 1 2 2 2 3 6 8 8 9
// https://www.youtube.com/watch?v=218qOVoVPKo
// https://leetcode.com/explore/learn/card/binary-search/135/template-iii/946/

int findCrossingPoint(vector<int> arr, int x){
    // OR find closet element (smallest possible)
    if(arr.size()==0){
        return -1;
    }
    if(arr.size()==1){
        return 0;
    }
    int start=0,end=arr.size()-1;
    while(start<end){
        if(start==end-1){
            if(abs(arr[start]-x)<=abs(arr[end]-x)){
                return start;
            }else{
                return end;
            }
        }
        int mid=start+(end-start)/2;
        if(arr[mid]==x){
            if(mid>0 && arr[mid]==arr[mid-1]){
                end=mid; // if clash left is preferred
                continue;
            }else{
                return mid;
            }       
        }else if(arr[mid]<x){
            start=mid;
        }else{
            end=mid;
        }
    }
}

vector<int> findClosestElements(vector<int>& arr, int k, int x) {
    int cross=findCrossingPoint(arr,x);
    cout<<"Cross: "<<cross<<endl;
    vector<int> index;
    index.push_back(arr[cross]);
    int l=cross-1,r=cross+1;
    int i=1; // cross is already added
    while(i<=k-1){
        if(l>=0 && r<arr.size()){
            if(abs(arr[l]-x)<=abs(arr[r]-x)){ // if both equal left is preferred in problem
                index.insert(index.begin()+0,arr[l]);
                l--;
            }else{
                index.push_back(arr[r]);
                r++;
            }
        }else if(l<0){
            index.push_back(arr[r]);
            r++;
        }else{
            index.insert(index.begin()+0,arr[l]);
            l--;
        }
        i++;
    }
    return index;
}

int main(){
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        vector<int> a(n);
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        int k,x;
        cin>>k>>x;
        cout<<"array"<<endl;
        for(int i=0;i<a.size();i++){
            cout<<a[i]<<" ";
        }
        cout<<endl;
        cout<<"k,x: "<<k<<" "<<x<<endl;
        vector<int> ans=findClosestElements(a,k,x);
        for(int i=0;i<ans.size();i++){
            cout<<ans[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}