陣列相關演算法

2022-03-27 05:21:04 字數 4367 閱讀 4282

1.尋找最小的k個數

有n個整數,請找出其中最小的k個數,要求時間複雜度盡可能低。

全部排序。使用快速排序演算法排序之後並且輸出最小的k個數,時間複雜度為o(nlogn)

def

quick_sort(array, left, right):

if left >=right:

return

low =left

high =right

key =array[low]

while left while left < right and array[right] >key:

right -= 1array[left] =array[right]

while left < right and array[left] <=key:

left += 1array[right] =array[left]

array[left] =key

quick_sort(array, low, left-1)

quick_sort(array, left+1, high)

以上為一般的快速排序演算法。由於是對陣列直接進行操作,不需要返回值。

線性選擇演算法

在選擇第k個最小元素時其平均時間複雜度為o(n)。

演算法思想很簡單,類似於快速排序。

我寫的快速排序暫時有bug,以後再修改上傳。

2.尋找和為定值的兩個數

輸入乙個整數陣列和乙個整數,在陣列中查詢一對數,滿足它們的和正好是輸入的那個整數。

如果有多對數的和等於輸入的整數,輸出任意一對即可。

窮舉法

def

two_sum(array, n):

len_a =len(array)

for i in

range(len_a):

for j in

range(len_a):

if i != j and array[i] + array[j] ==n:

return array[i], array[j]

排序夾逼

先利用快速排序將陣列變為有序陣列,然後利用二分查詢。可以將時間複雜度降為o(nlogn)。

或者是利用快速排序將陣列變為有序陣列後,使用兩個指標從兩段往中間掃瞄,這樣查詢的時間複雜度為o(n)。

def

binary_search(list_a, n):

low =0

high = len(list_a)-1

while low <=high:

mid = (low+high)/2

if list_a[mid] ==n:

return

true

elif list_a[mid] low = mid+1

else

: high = mid-1

return

false

deftwo_sum(array, n):

array.sort()

for i in

array:

if binary_search(array, n-i):

if array.index(i)!=array.index(n-i):

return i, n-i

如果n是其中乙個數的兩倍,則會出現bug。即陣列中的乙個數的出現了兩次,2i == n。因此需要附加額外的判斷條件。

def

two_sum(array, n):

begin =0

end = len(array)-1

while begin if array[begin]+array[end] ==n:

return

array[begin], array[end]

elif array[begin]+array[end] begin += 1

else

: end -= 1

與上面的相比,這個演算法需要陣列本身為有序。

不需要額外的判斷條件防止i和n-i為同乙個數的這種特殊情況。

3.尋找和為定值的多個數

輸入兩個整數n和sum,要求從數列1,2,3,...,n中取任意個數,使其和等於sum,請將其中所有可能的組合列出來。

n問題轉化為n-1問題

思路是如果取第n個數,問題轉化為n-1和sum-n的問題

如果不取第n個數,問題轉化為n-1和sum的問題

實現部分還有一點看不懂,所以暫時跳過。以後有機會補上。

4.最大連續子陣列和

給定乙個整數陣列,陣列裡可能有整數,負數和零。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。

求所有子陣列的和的最大值。

蠻力列舉

def

max_substring(array, length):

max_sum =array[0]

cur_sum =0

for i in

range(length):

for j in

range(i, length):

for k in range(i, j+1):

cur_sum +=array[k]

if cur_sum >max_sum:

max_sum =cur_sum

cur_sum =0

return max_sum

動態規劃

def

max_substring(array, length):

max_sum =array[0]

cur_sum =0

for i in

range(length):

if cur_sum >=0:

cur_sum +=array[i]

else

: cur_sum =array[i]

if cur_sum >max_sum:

max_sum =cur_sum

return max_sum

此方法從前往後掃瞄一遍陣列,即完成求最大連續子陣列和的需求,所以時間複雜度為o(n)。

5.跳台階問題

乙個台階總共有n級,如果一次可以跳一級,也可以跳兩級,求總共有多少種跳法。

遞迴

def

fib(n):

if n == 1:

return 1

if n == 2:

return 2

if n > 2:

return fib(n-1)+fib(n-2)

遞推

def

fib(n):

a =0

b = 1

for i in

range(n):

a, b = b, a+b

return b

6.奇偶數排序

給定乙個整數陣列,請調整陣列中數的順序,使得所有奇數字於陣列的前半部分,所有偶數字於陣列的後半部分。

要求時間複雜度為o(n)。

若把奇數看成小的數,偶數看成大的數,那麼按照題目要求的奇數放在前面偶數放在後面,

就相當於小數放在前面大數放在後面,聯想一下快速排序的劃分過程,就是通過乙個主元把整個陣列分成大小兩部分。

劃分過程有以下兩種實現。

一頭一尾兩個指標同時往中間掃瞄

def

is_odd(n):

return (n & 1) == 1

defodd_even_sort(array, length):

if array == or length <=0:

return

low =0

high = length-1

while low ifis_odd(array[low]):

low += 1

elif

notis_odd(array[high]):

high -= 1

else

: array[low], array[high] = array[high], array[low]

一前一後兩個指標同時從左往右掃  如果前指標遇到的數比主元小,則後指標右移一位,然後交換各自指向的數。

def

odd_even_sort(array, length):

if array == or length <= 0:

return

i = -1

for j in

range(length):

ifis_odd(array[j]):

i += 1array[i], array[j] = array[j], array[i]

陣列相關演算法

問題1 列印1到最大的n位數 解法 一 直接求出n位數的最大值,然後直接從1開始列印 缺陷 可能會溢位,大數問題 void print1tomax int n for int i 1 icout cout 二 在字串上模擬數字加法 void print1tomax int n bool increm...

陣列求和相關演算法

問題1 輸入乙個陣列,在陣列中查詢兩個數,使得它們的和正好是target void findtwosum int a,int n,int target 問題2 輸入整數sum,找出所有和為sum的連續整數序列,至少包含兩個。例如輸入15,由於1 2 3 4 5 4 5 6 7 8 15,所有結果列印...

陣列的相關演算法

目錄 1 陣列找最值 2 陣列統計 求總和 均值 統計偶數個數等 3 反轉 4 複製 5 查詢 6 排序 1 陣列中找最值 思路 1 先假設第乙個元素最大 最小 2 然後用max min與後面的元素一一比較 示例 int arr 找最大值 int max arr 0 for int i 1 imax...