Java_Basic_smallsum

   【小和问题】:

在随机元素,随机数组大小的数组中,找出左边比右边元素小的所有元素之和。    例如:数组[4,2,5,1,7,3,6] 第一个元素4比2大,不算小和,5比4和2都大,那就是4+2=6;1比4和2和5都小,不算小和;7比前面的都大,那就是上次小和6+4+2+5+1=18;然后3前面比2和1大,那就是18+2+1=21;最后6比4、2、5、1、3都大,结果就是21+4+2+5+1+3=36。那么最后的结果就是36。

【代码】


public class SmallSum_08 {

	public static int main(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-l) >>1;
		// 左侧部分产生的小和 + 右侧部分产生的小和 + merge过程中产生的小和
		return mergeSort(arr, 1, mid) + mergeSort(arr, mid+1, r) + merge(arr, 1, mid, r);
	}
	
	public static int merge(int[] arr, int l, int m, int r) {
		int[] help = new int[r - l + 1];
		int i = 0;
		int p1 = l;
		int p2 = m + 1;
		int res = 0; // 初始化,一会要叠加。
		
		while (p1 <= m && p2 <= r) {
			// 如果p1比p2小,那么产生多少个小和呢?,因为P2后面都是有序的,所以是p2后面的个数*p1值,
			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 (i=0; i < help.length; i++) {
			arr[l + i] = help[i];
		}
		return res;
	}
	
}

猜你喜欢

转载自blog.csdn.net/sinat_15355869/article/details/81350363