小和问题

package Test01;
/*
 * 在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数组的小和。求一个数组 的小和。
 * 例子: [1,3,4,2,5]
 *  1左边比1小的数,没有; 
 *  3左边比3小的数,1; 
 *  4左边比4小的数,1、3;
 *   2左边比2小的数,1; 5左边比
 *   5小的数,1、3、4、2;
 *    所以小和为1+1+3+1+1+3+4+2=16
 */

public class SmallSum {

	public static void main(String[] args) {
		int[] arr = { 1, 4, 7, 2, 5, 8 }; //
		int m = SmallSummer(arr);
		System.out.println(m);
	}

	private static int SmallSummer(int[] arr) { // 归并排序
		if (arr == null || arr.length < 2) {
			return 0;
		}
		return mergeSort(arr, 0, arr.length - 1);

	}

	public static int mergeSort(int[] arr, int L, int R) {
		if (L == R)
			return 0;

		int mid = (L + R) / 2; // 分治的思想
		return mergeSort(arr, L, mid) + mergeSort(arr, mid + 1, R) + merge(arr, L, mid, R);
	}

	public static int merge(int[] arr, int L, int mid, int R) {
		int count = 0;
		int a = L;
		int b = mid + 1;
		int i = 0;
		int[] help = new int[R - L + 1];

		while (a <= mid && b <= R) {
			if (arr[a] < arr[b]) {
				count = (R - b + 1) * arr[a] + count;
				help[i++] = arr[a++];
			} else {
				help[i++] = arr[b++];
			}
		}

		while (b <= R) {
			help[i++] = arr[b++];
		}
		while (a <= mid) {
			help[i++] = arr[a++];
		}
		for (i = 0; i < help.length; i++) {
			arr[L + i] = help[i];
		}

		return count;
	}

}
原文地址:https://www.cnblogs.com/superfly123/p/10524776.html