在乙個陣列中, 每乙個數左邊比當前數小的數累加起來, 叫做這個陣列的小和。 求乙個陣列的小和。
描述:[1, 3, 2, 51, 5]
1左邊比1小的數 0;
3左邊比3小的數 1;
2左邊比2小的數 1;
51左邊比51小的數 2,3,1;
5左邊比5小的數 2,3,1;
所以小和為0+1+1+2+3+1+2+3+1=14;
解題思路
轉換思想:上述例子我們要求5左面比5小的所有數的和可以轉換成 :
求1右面比1大的數的個數×1本身+3右面比3大的數個數×3本身**+2右面比2大的數的個數×2本身+51右面比51大的數的個數×51本身+5右面比5大的數的個數×**5本身。
如何理解?
上述例子中從1開始遍歷求到5計算小和,那麼1總共被加了4次因為3比1大,2比1大,51比1大,5比1大, 所以就是1*4;同理每個元素的小和就是本身×後面比他大的個數,之後加起來就是最終答案。
如此一來問題轉換為:
[1, 3, 2, 51, 5]
1右邊比1大的個數本身 4×1=4;
3右邊比3大的個數本身 3×2=6;
2右邊比2大的個數本身 2×2=4;
51右邊比51大的個數本身 5×1=0;
5右邊比5大的個數*本身 5×0=0;
所以小和為4+6+4+0+0=14;
解決方案
暴力破解這裡就不說了,雙層for迴圈遍歷判斷右面數比左面大就計數++,時間複雜度為o(n的平方)。
本題還可以用歸併排序處理。時間複雜度為o(n×logn)
在並的時候判斷以上邏輯並且累加即可。
**如下:
public class main ;
mergesort(arr, 0, arr.length - 1);
print_nums(arr);
system.out.println();
system.out.println(sum);
}public static void mergesort(int arr, int l, int r)
int mid = l + (r - l) / 2;
mergesort(arr, l, mid);
mergesort(arr, mid + 1, r);
merge(arr, l, mid, r);
}public static void merge(int arr, int l, int mid, int r)
while (pl <= mid)
while (pr <= r)
for (i = 0; i < help.length; i++)
}public static void print_nums(int nums)
}123
4567
891011
1213
1415
1617
1819
2021
2223
2425
2627
2829
3031
3233
3435
3637
3839
4041
4243
4445
4647
4849
5051
5253
同理也可以求數列的逆序數
/* public static void print_nums(int nums)
}*/
歸併排序 小和問題
public class mergesort sortprocess arr,0,arr.length 1 遞迴 public static void sortprocess int arr,int l,int r int mid l r l 1 sortprocess arr,l,mid t n ...
歸併排序 小和問題
問題描述 在乙個陣列中,每乙個數左邊比當前數小的數累加起來,叫做這個陣列的小和。求乙個陣列的小和。樣例 1,3,4,2,5 1左邊比1小的數,沒有 3左邊比3小的數,1 4左邊比4小的數,1 3 2左邊比2小的數,1 5左邊比5小的數,1 3 4 2 所以小和為1 1 3 1 1 3 4 2 16 ...
小和問題 歸併排序
在乙個陣列中,每乙個數左邊比當前數小的數累加起來,叫做這個陣列的小和。例子 輸入 1,3,4,2,5 輸出 16 1左邊比1小的數,沒有 3左邊比3小的數,1 4左邊比4小的數,1 3 2左邊比2小的數,1 5左邊比5小的數,1 3 4 2 所以小和為1 1 3 1 1 3 4 2 16實現的基本原...