左神面试算法整理--并归求小和

来源:互联网 发布:贷款抢单软件 编辑:程序博客网 时间:2024/06/08 13:46

算法思想:

此题是求小和问题,求小和问题要用归并排序的思想来解决,只需在并归上稍作修改即可,所以我们要先看一下并归排序。

并归排序的基础知识参见博文:http://blog.csdn.net/left_la/article/details/8656953


本题对归并排序稍作修改,在归并排序时,左边块起始left和右边块起始right进行比较时,若left<right的值,则就加上right及其右边数的个数*left的值。其它和归并过程一样,由小和的定义可以知道,在归并排序过程中,如果左块比右块小,那么遍历到右块数时,都要加一次左块上的那个数。由归并排序可知,这一次排好的块,在下一次和新的右块排序时,此块内数是不在进行比较的,所以不会出现重复加值的情况。

JAVA版

package problems_2017_07_26;


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));


}


}

C++版

#include<iostream>
#include<stack>
#include<string>

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<end-pre+1;p++)
a[pre++]=h[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"<<endl;
int result=sort(a,0,5);

cout<<result<<endl;
system("pause");
return 0;
}


原创粉丝点击