given an array, for each element, find out the total number of elements lesser than it, which appear to the right of it

后端 未结 10 1795
傲寒
傲寒 2021-02-04 11:43

I had previously posted a question, Given an array, find out the next smaller element for each element now, i was trying to know , if there is any way to find out \"given an ar

相关标签:
10条回答
  • 2021-02-04 12:06

    It can be solved in O(n log n).

    If in a BST you store the number of elements of the subtree rooted at that node when you search the node (reaching that from the root) you can count number of elements larger/smaller than that in the path:

    int count_larger(node *T, int key, int current_larger){
        if (*T == nil)
            return -1;
        if (T->key == key)
            return current_larger + (T->right_child->size);
        if (T->key > key)
            return count_larger(T->left_child, key, current_larger + (T->right_child->size) + 1);
        return count_larger(T->right_child, key, current_larger)
    }
    

    ** for example if this is our tree and we're searching for key 3, count_larger will be called for:

    -> (node 2, 3, 0)
    --> (node 4, 3, 0)
    ---> (node 3, 3, 2)

    and the final answer would be 2 as expected.

    0 讨论(0)
  • 2021-02-04 12:11

    Another approach without using the tree.

    1. Construct another sorted array . For example for input array {12, 1, 2, 3, 0, 11, 4} it will be {0, 1, 2, 3, 4, 11, 12}
    2. Now compare position of each element from input array with sorted array.For example 12 in first array is at 0 index while sorted array it’s as 6
    3. Once comparison is done, remove element from both array
    0 讨论(0)
  • 2021-02-04 12:13

    Other than using BST, we can also solve this problem optimally by doing some modification in merge sort algorithm (in O(n*logn) time).

    If you observe this problem more carefully, you can say that in the problem we need to count the number of inversions required for each element to make the array sorted in ascending order, right?

    So this problem can be solved using Divide and Conquer paradigm. Here you need to maintain an auxiliary array for storing the count of inversions required (i.e. elements smaller than it on the right side of it).

    Below is a python program:

    def mergeList(arr, pos, res, start, mid, end):
        temp = [0]*len(arr)
        for i in range(start, end+1):
            temp[i] = pos[i]
    
        cur = start
        leftcur = start
        rightcur = mid + 1
    
        while leftcur <= mid and rightcur <= end:
    
            if arr[temp[leftcur]] <= arr[temp[rightcur]]:
                pos[cur] = temp[leftcur]
                res[pos[cur]] += rightcur - mid - 1
                leftcur += 1
                cur += 1
            else:
                pos[cur] = temp[rightcur]
                cur += 1
                rightcur += 1
    
        while leftcur <= mid:
            pos[cur] = temp[leftcur]
            res[pos[cur]] += end - mid
            cur += 1
            leftcur += 1
    
        while rightcur <= end:
            pos[cur] = temp[rightcur]
            cur += 1
            rightcur += 1
    
    
    def mergeSort(arr, pos, res, start, end):
        if start < end:
            mid = (start + end)/2
            mergeSort(arr, pos, res, start, mid)
            mergeSort(arr, pos, res, mid+1, end)
            mergeList(arr, pos, res, start, mid, end)
    
    
    def printResult(arr, res):
        print
        for i in range(0, len(arr)):
            print arr[i], '->', res[i]
    
    
    if __name__ == '__main__':
        inp = input('enter elements separated by ,\n')
        inp = list(inp)
        res = [0]*len(inp)
        pos = [ind for ind, v in enumerate(inp)]
        mergeSort(inp, pos, res, 0, len(inp)-1)
        printResult(inp, res)
    

    Time : O(n*logn)

    Space: O(n)

    0 讨论(0)
  • 2021-02-04 12:16

    You can also use binary Index tree

    int tree[1000005];
    void update(int idx,int val)
    {
       while(idx<=1000000)
       {
           tree[idx]+=val;
           idx+=(idx & -idx);
       }
    }
    
    int sum(int idx)
    {
        int sm=0;
        while(idx>0)
        {
           sm+=tree[idx];
           idx-=(idx & -idx);
        }
        return sm;
    }
    
    int main()
    {
        int a[]={4,2,1,5,3};
        int s=0,sz=6;
        int b[10];
        b[sz-1]=0;
        for(int i=sz-2;i>=0;i--)
        {
            if(a[i]!=0)
            {
                update(a[i],1);
                b[i]=sum(a[i]-1)+s;
            }
            else s++;
        }
        for(int i=0;i<sz-1;i++)
        {
           cout<<b[i]<<" ";
        }
       return 0;
    }
    
    0 讨论(0)
提交回复
热议问题