【題目】
陣列小和的定義如下:
例如:陣列s = [1, 3, 5, 2, 4, 6],在s[0]的左邊小於或者等於s[0]的數的和為0,在s[1]的左邊小於或等於s[1]的數的和為1……將所有位置的左邊比它小或者等於的數的和相加起來就是小和。
給定乙個陣列,實現函式返回s的小和。
【基本思路】
最簡單易懂的方法,就是依次遍歷陣列每乙個位置 i,然後再遍歷一次找到 i 左邊所有小於或者等於 s[i] 的數,累加即可。該時間複雜度為o(n^2)。
我們可以換一種思路考慮這個問題,對於每乙個位置 i 的值s[i],我們計算它比右邊的幾個數小或者等於,假設這樣的數有 num 個,那麼在最後的小和中,s[i]提供的值的總和就是s[i] * num。顯而易見,將每乙個位置的 s[i] * num 加起來就是最終的小和。
使用歸併排序的過程可以達到這個目的,試想,在歸併排序的組間合併過程中,左右兩組都已經有序。假設左組為left,右組為right,並分別從位置 i 和 j 開始比較。如果left[i] <= right[j],可以肯定right陣列 j 位置右邊的所有位置(假設有n個)的值都一定比left[i]大或等於,所以會產生乙個小和left[i] * n。當然這時的n不是原陣列中所有在left[i]右邊比left[i]大或等於的數,因為left和right只是原陣列中的兩個子陣列。
整個歸併過程該怎麼進行就怎麼進行,排序過程沒有任何變化,只是在組間合併的時候計算所有產生的小和並累加起來就是最終的結果。整個過程時間複雜度o(nlogn)。
下面是用python3.5實現的**。
def
getsmallsum
(arr):
defmergesort
(arr, start, end):
if start == end:
return
0 mid = (start + end) // 2
return mergesort(arr, start, mid) + mergesort(arr, mid+1, end) + merge(arr, start, mid, end)
defmerge
(arr, start, mid, end):
left = start
right = mid + 1
res =
sum = 0
while left <= mid and right <= end:
if arr[left] < arr[right]:
sum += arr[left] * (end - right + 1)
left += 1
else:
right += 1
res += arr[left : mid+1]
res += arr[right : end+1]
for i in range(start, end+1):
arr[i] = res.pop(0)
return sum
if arr == none
or len(arr) == 0:
return
0return mergesort(arr, 0, len(arr)-1)
計算陣列的小和
題目 陣列小和的定義如下 例如,陣列s 1,3,5,2,4,6 在s 0 的左邊小於或等於s 0 的數的和為0,在s 1 的左邊小於或等於s 1 的數的和為1,在s 2 的左邊小於或等於s 2 的數的和為1 3 4,在s 3 的左邊小於或等於s 3 的數的和為1,在s 4 的左邊小於或等於s 4 的...
計算陣列的小和
陣列小和的定義如下 例如,陣列s 1,3,5,2,4,6 在s 0 的左邊小於或等於s 0 的數的和為0 在s 1 的左邊小於或等於s 1 的數的和為1 在s 2 的左邊小於或等於s 2 的數的和為1 3 4 在s 3 的左邊小於或等於s 3 的數的和為1 在s 4 的左邊小於或等於s 4 的數的和...
階乘計算 陣列
問題描述 輸入乙個正整數n,輸出n 的值。其中n 1 2 3 n。演算法描述 n 可能很大,而計算機能表示的整數範圍有限,需要使用高精度計算的方法。使用乙個陣列a來表示乙個大整數a,a 0 表示a的個位,a 1 表示a的十位,依次類推。將a乘以乙個整數k變為將陣列a的每乙個元素都乘以k,請注意處理相...