算法思想:
此题是求小和问题,求小和问题要用归并排序的思想来解决,只需在并归上稍作修改即可,所以我们要先看一下并归排序。
并归排序的基础知识参见博文:http://blog.csdn.net/left_la/article/details/8656953
本题对归并排序稍作修改,在归并排序时,左边块起始left和右边块起始right进行比较时,若left JAVA版 package problems_2017_07_26; C++版 #include
public class Problem_02_SmallSum {
public static int getSmallSum(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
return func(arr, 0, arr.length - 1);
}
public static int func(int[] s, int l, int r) {
if (l == r) {
return 0;
}
int mid = (l + r) / 2;
return func(s, l, mid) + func(s, mid + 1, r) + merge(s, l, mid, r);
}
public static int merge(int[] s, int left, int mid, int right) {
int[] h = new int[right - left + 1];
int hi = 0;
int i = left;
int j = mid + 1;
int smallSum = 0;
while (i <= mid && j <= right) {
if (s[i] <= s[j]) {
smallSum += s[i] * (right - j + 1);
h[hi++] = s[i++];
} else {
h[hi++] = s[j++];
}
}
for (; (j < right + 1) || (i < mid + 1); j++, i++) {
h[hi++] = i > mid ? s[j] : s[i];
}
for (int k = 0; k != h.length; k++) {
s[left++] = h[k];
}
return smallSum;
}
public static void swap(int[] arr, int index1, int index2) {
int tmp = arr[index1];
arr[index1] = arr[index2];
arr[index2] = tmp;
}
public static void main(String[] args) {
int[] arr = { 3, 1, 2, 4, 6, 2, 7, 8, 1 };
System.out.println(getSmallSum(arr));
}
}
#include
#include
using namespace std;
int merge_sort(int* a,int pre,int mid,int end)
{
int i=pre;
int j=mid+1;
int k=0;
int* h=new int[end-pre+1];
int count=0;
while(i<=mid&&j<=end)
{
if(a[i]<=a[j])
{
count+=a[i]*(end-j+1);
h[k++]=a[i++];
}
else
h[k++]=a[j++];
}
for(;(i<=mid)||(j<=end);i++,j++)
h[k++]=i>mid?a[j]:a[i];
for(int p=0;p
delete []h;
return count;
}
int sort(int* a, int pre,int end)
{
if(pre==end)
return 0;
int mid=(pre+end)/2;
return sort(a,pre,mid)+ sort(a,mid+1,end)+merge_sort(a,pre,mid,end);
}
int main()
{
int a[6]={1,3,5,2,4,6};
if(a==NULL)
cout<<"0"<
cout<
return 0;
}