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

后端 未结 10 1793
傲寒
傲寒 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:00

    Modified Merge sort: (Already tested code)

    Takes O(nlogn) time.

    public class MergeSort {
        static HashMap valueToLowerCount = new HashMap();
    
        public static void main(String[] args) {
            int []                 arr = new int[] {50, 33, 37, 26, 58, 36, 59};
            int [] lowerValuesOnRight  = new int[] {4,   1,  2,  0,  1,  0,  0};
    
            HashMap expectedLowerCounts = new HashMap();
            idx = 0;
            for (int x: arr) {
                expectedLowerCounts.put(x, lowerValuesOnRight[idx++]);
            }
            
            for (int x : arr) valueToLowerCount.put(x, 0);
            
            mergeSort(arr, 0, arr.length-1);
            
            //Testing       
            Assert.assertEquals("Count lower values on right side", expectedLowerCounts, valueToLowerCount);
        }
        public static void mergeSort(int []arr, int l, int r) {
            if (r <= l) return;
            int mid = (l+r)/2;
            mergeSort(arr, l, mid);
            mergeSort(arr, mid+1, r);
            mergeDecreasingOrder(arr, l, mid, r);
        }
        public static void mergeDecreasingOrder(int []arr, int l, int lr, int r) {
            int []leftArr = Arrays.copyOfRange(arr, l, lr+1);
            int []rightArr = Arrays.copyOfRange(arr, lr+1, r+1);
            int indexArr = l;
            int i = 0, j = 0;
            while (i < leftArr.length && j < rightArr.length) {
                if (leftArr[i] > rightArr[j]) {
                    valueToLowerCount.put(leftArr[i], valueToLowerCount.get(leftArr[i]) + rightArr.length - j);
                    arr[indexArr++] = leftArr[i++];
                }else {
                    arr[indexArr++] = rightArr[j++];
                }
            }
            while (i < leftArr.length)  { 
                arr[indexArr++] = leftArr[i++]; 
            }
            while (j < rightArr.length) {
                arr[indexArr++] = rightArr[j++];
            }
        }   
    }
    

    To find the total number of values on right-side which are greater than an array element, simply change single line of code:

    if (leftArr[i] > rightArr[j])
    

    to

    if (leftArr[i] < rightArr[j])
    

提交回复
热议问题