Inversion Count for an array indicates – how far (or close) the array is from being sorted. If array is already sorted then inversion count is 0. If array is sorted in reverse order that inversion count is the maximum.
Formally speaking, two elements a[i] and a[j] form an inversion if a[i] > a[j] and i < j
Example:
Input: arr[] = {8, 4, 2, 1}
Output: 6
Explanation: Given array has six inversions:
(8,4), (4,2),(8,2), (8,1), (4,1), (2,1).
Input: arr[] = {3, 1, 2}
Output: 2
Explanation: Given array has two inversions:
(3, 1), (3, 2)
classGFG {// Some Question// Why this works ?// 1) When we are merging the sorted parts, then we have already taken care of// inversions within each part, therefore we only need to take care of// inversions with the other part// 2) We need to understand that when we compare i & j in sorted order, you// might think that we need inversion in unsorted array// But remember that 1st part is sorted within itself that means that value at// index i, will be before j value in the original array aswellpublicstaticlongmerge(int[] arr,int start,int end) {int mid = start + (end - start) /2;int[] holderArr =newint[end - start +1];int pointer1 = start, pointer2 = mid +1, index =0;long inversions =0;while (pointer1 <= mid && pointer2 <= end) {if (arr[pointer1] <= arr[pointer2]) holderArr[index++] = arr[pointer1++];// If arr[i] > arr[j], then all the elements will be > arr[j]// because it is sorted arrayelse { inversions += (mid - pointer1 +1); holderArr[index++] = arr[pointer2++]; } }while (pointer1 <= mid) holderArr[index++] = arr[pointer1++];while (pointer2 <= end) holderArr[index++] = arr[pointer2++];// Copying the changes into original arrayfor (int i = start; i <= end; i++) arr[i] = holderArr[i - start];return inversions; }publicstaticlongmergeSort(int[] arr,int start,int end) {if (start >= end)return0L;int mid = start + (end - start) /2;long leftInversions =mergeSort(arr, start, mid);long rightInversions =mergeSort(arr, mid +1, end);return leftInversions + rightInversions +merge(arr, start, end); }publicstaticlongcountInversions(int[] arr) {returnmergeSort(arr,0,arr.length-1); }}
Question - 2
Once detective Saikat was solving a murder case. While going to the crime scene he took the stairs and saw that a number is written on every stair. He found it suspicious and decides to remember all the numbers that he has seen till now. While remembering the numbers he found that he can find some pattern in those numbers. So he decides that for each number on the stairs he will note down the sum of all the numbers previously seen on the stairs which are smaller than the present number. Calculate the sum of all the numbers written on his notes diary.
Answer may not fit in integer . You have to take long.
Input
First line gives T, number of test cases.
2T lines follow.
First line gives you the number of stairs N
Next line gives you N numbers written on the stairs.
Output
For each test case output one line giving the final sum for each test case.
Output
For each test case output one line giving the final sum for each test case.
Constraints
T<=10
1<=N<=10^5
All numbers will be between 0 and 10^6.
Sample Input:
1
5
1 5 3 6 4
Sample Output:
15
Explanation:
For the first number, the contribution to the sum is 0.
For the second number, the contribution to the sum is 1.
For the third number, the contribution to the sum is 1.
For the fourth number, the contribution to the sum is 9 (1+5+3).
For the fifth number, the contribution to the sum is 4 (1+3).
Hence the sum is 15 (0+1+1+9+4).
publicclassMain {publicstaticlongmerge(intA[],int left,int right) {int mid = left + (right - left) /2;int pointer1 = left, pointer2 = mid +1, index =0;int temp[] =newint[right - left +1];long count =0;while (pointer1 <= mid && pointer2 <= right) {// If arr[p1] is smaller that arr[p2], then arr[p1] will be smaller than all the// elements following arr[p2]if (A[pointer1] <A[pointer2]) { count +=A[pointer1] * (right - pointer2 +1); temp[index++] =A[pointer1++]; } else temp[index++] =A[pointer2++]; }while (pointer1 <= mid) temp[index++] =A[pointer1++];while (pointer2 <= right) temp[index++] =A[pointer2++];for (int i = left; i <= right; i++)A[i] = temp[i - left];return count; }publicstaticlongmergeSort(int arr[],int left,int right) {if (left >= right)return0L;int mid = left + (right - left) /2;long leftSum =mergeSort(arr, left, mid);long rightSum =mergeSort(arr, mid +1, right);long mergeSum =merge(arr, left, right);return (mergeSum + leftSum + rightSum); }publicstaticlongrequiredSum(int[] arr,int n) {returnmergeSort(arr,0, n -1); }}
Question - 3
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.
Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.
Note:
A naive algorithm of O(n2) is trivial. You MUST do better than that.
Example:
Input: nums = [-2,5,-1], lower = -2, upper = 2,
Output: 3
Explanation: The three ranges are : [0,0], [2,2], [0,2] and their respective sums are: -2, -1, 2.
classSolution {int lower, upper;publicintcountRangeSum(int[] nums,int lower,int upper) {long[] prefixSum =newlong[nums.length+1];this.lower= lower;this.upper= upper;// PrefixSum[i] -> Sum of first i elementsfor (int i =1; i <=nums.length; i++) prefixSum[i] = prefixSum[i -1] + nums[i -1];returnmergeSort(prefixSum,0,prefixSum.length-1); }privateintmergeSort(long[] prefixSum,int start,int end) {if (start >= end)return0;int mid = start + (end - start) /2;// The pairs in the left half and the pairs in the // right half get counted in the recursive calls.int leftAns =mergeSort(prefixSum, start, mid);int rightAns =mergeSort(prefixSum, mid +1, end);// We just need to also count the pairs that use both halves.return leftAns + rightAns +merge(prefixSum, start, end); }privateintmerge(long[] prefixSum,int start,int end) {int ans =0, mid = start + (end - start) /2;long[] temp =newlong[end - start +1];int pointer1 = start, pointer2 = mid +1, index =0;int left = mid +1, right = mid +1;// O(N), because "left" & "right" variables only move rightwhile (pointer1 <= mid) {// We find a limit, such that we just enter "lower" limitwhile (left <= end && prefixSum[left] - prefixSum[pointer1] < lower) left++;// We find a limit, such that we just get out of "upper" limitwhile (right <= end && prefixSum[right] - prefixSum[pointer1] <= upper) right++;// Normal merging processwhile (pointer2 <= end && prefixSum[pointer2] < prefixSum[pointer1]) temp[index++] = prefixSum[pointer2++]; temp[index++] = prefixSum[pointer1++];// Answer will be [L,R], L is shown by pointer1, & // R is shown by all the values in between [left,right) ans += right - left; }while (pointer2 <= end) temp[index++] = prefixSum[pointer2++];for (int i = start; i <= end; i++) prefixSum[i] = temp[i - start];return ans; }}
Question - 4
You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].
Example:
Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.
classSolution {staticclassPair {int val, i;Pair(int val,int index) {this.val= val;this.i= index; } }List<Integer> ans;publicList<Integer> countSmaller(int[] nums) {// Creating answer array ans =newArrayList<>();Pair[] arr =newPair[nums.length];for (int i =0; i <arr.length; i++) {ans.add(0); arr[i] =newPair(nums[i], i); }mergeSort(arr,0,nums.length-1);return ans; }publicvoidmergeSort(Pair[] arr,int start,int end) {if (start >= end)return;int mid = start + (end - start) /2;mergeSort(arr, start, mid);mergeSort(arr, mid +1, end);merge(arr, start, end); }publicvoidmerge(Pair[] arr,int start,int end) {int mid = start + (end - start) /2;Pair[] temp =newPair[end - start +1];int index =0, pointer1 = start, pointer2 = mid +1;int limit = mid +1;while (pointer1 <= mid) {// For every element in the left part, we are finding count of // elements in right part < elementwhile (limit <= end && arr[limit].val< arr[pointer1].val) limit++;ans.set(arr[pointer1].i,ans.get(arr[pointer1].i) + limit - (mid +1));// Merge processwhile (pointer2 <= end && arr[pointer2].val< arr[pointer1].val) temp[index++] = arr[pointer2++]; temp[index++] = arr[pointer1++]; }while (pointer2 <= end) temp[index++] = arr[pointer2++];for (int i = start; i <= end; i++) arr[i] = temp[i - start]; }}
Question - 5
Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].
You need to return the number of important reverse pairs in the given array.
Example1:
Input: [1,3,2,3,1]
Output: 2
Example2:
Input: [2,4,3,5,1]
Output: 3
Note:
The length of the given array will not exceed 50,000.
All the numbers in the input array are in the range of 32-bit integer.