题目:给你一个数组,请输出这个数组中的小和是多少?
小和:在一个数组中,每一个数的左边的数比当前数小的数累加起来
eg:[1,3,4,2,5]
比1小:无
比3小:1
比4小:1,3
比2小:1
比5小:1,3,4,2
小和:1+1+3+1+1+3+4+2=16
方法一:暴力枚举
public class demo {
public static void main(String[] args) {
int[] nums = {5,3,1,2,6};
int sum = getSmallSum(nums);
System.out.println(sum);
}
/**
* 得到小和
* @param nums - 需要求小和的数组
* */
public static int getSmallSum(int[] nums) {
if(nums.length<=1){//如果数组长度小于1,那么数组中的元素只有1个或0个,那么不产生小和
return 0;
}
int sum=0;
for(int i =0 ;i<nums.length;i++){
for(int j =0 ;j<i;j++){
if(nums[j]<nums[i]){//左边的数比这个数小
sum += nums[j];
}
}
}
return sum;
}
}
方法二:分治
public class demo {
public static void main(String[] args) {
int[] nums = {5, 3, 1, 2, 6};
int start = 0;
int end = nums.length - 1;
//递归
int sum = process(nums, start, end);
System.out.println(sum);
}
/**
* @param nums - 需要递归的数组
* @param start - 开始下标
* @param end - 结束下标
* @return int - 返回在递归过程中产生的小和
*/
public static int process(int[] nums, int start, int end) {
if(nums.length<=1){
return 0;
}
if (start == end) {
return 0;
}
//中点
int middle = start + ((end - start) >> 1);
/*
* process(nums, start, middle)---左边递归产生的小和
* process(nums, middle + 1, end)---右边递归产生的小和
* getSmallSum(nums, start, middle, end)----归并过程产生的小和
* */
return process(nums, start, middle)+process(nums, middle + 1, end)+getSmallSum(nums, start, middle, end);
}
/**
* 得到小和
* @param nums - 需要求小和的数组
* @param start - 开始下标
* @param middle - 中间下标
* @param end - 结束下标
*/
public static int getSmallSum(int[] nums, int start, int middle, int end) {
//定义一个新的数组
int[] newArray = new int[end + 1];
//从传入数组的开始下标开始改变原数组的顺序
int i = start;
//从传入的数组开始下标开始进行比较
int tempLeft = start;
int tempRight = middle + 1;
//小和
int res = 0;
while (tempLeft <= middle && tempRight <= end) {
//如果左边的指针小于右边的指针所代表的数,那么产生小和,比左边指针大的个数为end-tempRight+1
res += nums[tempLeft] < nums[tempRight] ? nums[tempLeft]*(end-tempRight+1) : 0;
newArray[i++] = nums[tempLeft] < nums[tempRight] ? nums[tempLeft++] : nums[tempRight++];
}
while(tempLeft <= middle){
newArray[i++] = nums[tempLeft++];
}
while(tempRight <= end){
newArray[i++] = nums[tempRight++];
}
//改变原数组的顺序
for(i =start ; i<newArray.length;i++){
nums[i]=newArray[i];
}
return res;
}
}