【编程题】小和问题(java实现)
题目描述
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数的小和,求一个数组的小和;
例如:
【1,3,4,2,5】
1左边比1小的数:没有
3左边比3小的数:1
4左边比5小的数:1,3
2左边比2小的数:1
5左边比5小的数:1,3,4,2
所以小和为:1+1+3+1+1+3+4+2=16
解答
方法一,暴力法
时间复杂度O(n^2)
package practice;
public class SmallSum {
public static void main(String[] args){
int[] a={1,3,4,2,5};
int sum= smallSum(a);
System.out.println(sum);
}
static int smallSum(int[] arr){
if(arr==null||arr.length<=0)
return 0;
int sum=0;
for(int i=0,len=arr.length;i<len;i++){
for(int j=0;j<i;j++){
if(arr[j]<arr[i])
sum+=arr[j];
}
}
return sum;
}
}
归并法
时间复杂度O(nlogn)
package practice;
public class Sum {
public static void main(String[] args){
int[] a={1,3,4,2,5};
int sum= sum(a);
System.out.println(sum);
}
static int sum(int[] arr){
if(arr==null||arr.length<=0)
return 0;
return sum(arr,0,arr.length-1);
}
static int sum(int[] arr,int low,int high){
if(low==high)
return 0;
int mid=(low+high)>>1;
int left= sum(arr,low,mid);
int right=sum(arr,mid+1,high);
int merg= merge(arr,low,high);
return left+right+merg;
}
static int merge(int[] arr,int low,int high){
int index=0;
int mid=(low+high)>>1;
int i=low,j=mid+1;
int[] help=new int[high-low+1];
int sum=0;
while (i<=mid&&j<=high){
if(arr[i]<arr[j])
sum+=(high-j+1)*arr[i];
help[index++]=arr[i]<arr[j]?arr[i++]:arr[j++];
}
while (i<=mid){
help[index++]=arr[i++];
}
while (j<=high){
help[index++]=arr[j++];
}
for(int k=low;k<=high;k++)
arr[k]=help[k-low];
return sum;
}
}