(Algorithm) The extension of merge sort, the small sum problem and the reverse order problem. (Ultra-detailed nanny-level explanation)

small sum problem

  • brief description

 There is an array, we traverse from left to right, and every time we move to a bit, we add all the numbers to the left of it that are smaller than it, and the final sum is recorded as the small sum. The following is an example of a common practice process:

So what we need is a faster approach.

  •  analysis logic

We can still use the previous merge sort and modify the merge part.

Take the following as an example, still divide the array into two

figure 1

figure 2 

Still prepare two indicators, and an empty list help

Look at 1 on the left, p1 on the left of 3 points to 1 and p2 on the right points to 3, compare, 1<3, add 1 to the small sum, store 1 in the help list, move the index p1 right out of bounds (there is no number on the left), and directly copy the 3 on the right Enter the help list, and then copy the help list into the array. (help[1,3])

Enter the upper layer, p1 points to 1, p2 points to 2, 1<2, add 1 to the small sum, store 1 in the help list, p1 points to 3, 3>2, add 0 to the small sum, store 2 in the help list, there is no number on the right Now, copy the rest on the left directly into the help list (help[1, 2, 3])

(5, 6 are the same)

Enter the upper layer, at this time the left and right sides have been sorted, p1 points to 1, p2 points to 5, 5>1, (because the right side is also in order, all the numbers after 5 are greater than 1, then proceed directly Just calculate the subscript) add 1*2 to the small sum, store 1 in the help list, p1 points to 2, and add 2*2 to the small sum if 5>2, store 2 in the help list, and so on, and finally the entire array has order, and find the minimum sum of the array.

(ps: 1. If the number on the left is greater than the number on the right, store the number on the right in the help list, and the p2 indicator will move one bit to the right, that is, whoever is smaller will enter the help; 2. Because every time the sum is calculated, the sorted, so sorting doesn't affect the result)

  •  Code (Java):
 public static int process(int[] arr,int L,int R){
  if(L==R){
    return;
  }
  int M = L+((R-L)>>1);
  merge(arr,L,M,R);
  return process(arr,L,M)+process(arr,M+1,R)+merge(arr, L,M,R);
}  

public static int merge(int[] arr,int L,int R){
  int p1 = L;
  int p2 = M+1;
  int[] help = new int[R-L+1];
  int res =0;    //小和
  int i = 0;
  while(p1 <= M && p2 <= R){
    res += arr[p1] < arr[p2] ? (R - p2+1)*arr[p1]:0;    //左边小则该数乘右边下标数记小和
    help[i] = arr[p1] < arr[p2] ? arr[p1++]:arr[p2++];
  while(p1 <= M){
    help[i++] = arr[p1++]; 
  }
  while(p2 <= R){
    help[i++] = arr[p2++];
  }
  for(int i = 0,i < help.length,i++){
    arr[L+i] = help[i];    //把排好序的help拷贝到该次求小和数组范围
  return res;
  }
  }  
}

 reverse pair problem

  • brief description

In an array, if the number on the left is greater than the number on the right, it is recorded as a reverse pair. Its essence is the same as the previous small sum problem. We also only need to modify the merge. (To find the small sum is to find that the left side is smaller than the right side)

 The above is all the reversed pairs in the array.

Guess you like

Origin blog.csdn.net/qq_48860282/article/details/123939514