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

后端 未结 10 1797
傲寒
傲寒 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条回答
  •  慢半拍i
    慢半拍i (楼主)
    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)

提交回复
热议问题