小和問題(歸併排序)

2021-10-08 09:48:00 字數 1753 閱讀 2264

在乙個陣列中, 每乙個數左邊比當前數小的數累加起來, 叫做這個陣列的小和。 求乙個陣列的小和。

描述:[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實現的基本原...