演算法導論P23題目2 3 7

2022-08-01 13:48:10 字數 1762 閱讀 6290

請給出乙個執行時間為o(n lgn)的演算法,使之在給定乙個由n個整數構成的集合s和另乙個整數x時,判斷出s中是否存在有兩個其和等於x的元素。

以下思路一 和 思路二來自 

思路一 :我們最容易想到的是o(n2)的演算法,大致偽碼即:

1 findx(a, x)

6     }

7     return false

8 }這裡的演算法不符合o(n lgn),所以不行。

思路二:改進思路一中的演算法,使第一層迴圈裡面的4--5行的效率為 lgn。

既然4-5行的目的是找到某個符合條件的值,那麼我想到了二分查詢,二分查詢是乙個最壞o(lgn)的查詢演算法,但是前提是集合s有序,於是先要進行排序。偽碼如下:

1 findx(a, x)

7     }

8     return false

9 }第2行的歸併排序執行時間為o(n lgn), 第3-7行的執行時間為o(n)*o(lgn)= o(nlgn),故總執行時間為o(nlgn)。

思路三來自

思路三:

1.        對陣列s進行歸併排序。

2.        構造陣列s』=,並排序。由於s已經有序,構造與排序可一併完成。

3.        刪除s中重複的元素使僅保留乙個,對s』進行同樣的操作。

4.        合併s和s』,並保證合併後有序,這裡可以使用歸併排序的思想。

5.        如果在合併後的陣列中存在連續兩個相同的元素,並且這種元素的個數大於1,那麼有解。

設想在合併後的陣列中存在連續兩個w,則w分別屬於s和s』,那麼s中存在y使得w=x-y,即x=y+w。因此,s中元素w和y的和為x。

步驟1的執行時間為θ(n lg n),其餘步驟執行時間為θ(n),因此總的時間代價為θ(n lg n)。

思路四:前提是所有元素非負

1 首先通過合併排序對陣列元素排序,時間 o(nlgn)

2 用二分查詢方法找到乙個陣列下標 pend,使給定的 key≤array[i], 時間 o(lgn)

注意: p23頁的 2.3-6題的插入排序就可以用這種方法實現

3 在下標0 - pend之間搜尋滿足條件的資料,這裡用到思路二的思想。時間 o((pend)lg(pend))

**如下:

/*

* findsumofdata.cpp

* 演算法導論 p.23 2.3-7

* created on: 2011-12-27

* author: lichanghai

*/#include "

myheder.h"//

該函式尋找下標 pend

bool binaryfind(const

int array[ ], int n, int &pend, int key)

//只剩乙個元素時,確定 pend 的值

if(key >= array[low])

else

if(low != 0)

else

return

0; //

所有的資料都比 key 大,返回0表示沒找到

}bool findsumofdata(int array[ ], int n, int key)

//如果沒找到,返回0

return

0;}

演算法導論 2 3 7

問題 給定n個整數的集合s和另乙個整數x,描述乙個執行時間為o log n 的演算法,該演算法能夠確定s中是否存在兩個其和剛好為x的元素 演算法描述 1 先將集合中元素排序在陣列a中 2 對於集合中的每乙個元素a i 在排好序的陣列a中二分查詢 x a i 3 查詢成功則存在,迴圈結束後查詢未成功則...

演算法導論習題解答 2 3 7

2.3 7 請給出乙個執行為 nlgn 的演算法 偽碼 使之能在給定乙個由n 個整數構成的集合s 和另乙個整數x 時,判斷出s 中是否存在有兩個其和等於x 的元素。解 解題思路 先對集合s進行歸併排序,然後新建乙個陣列s1,使得s1 i x s i 再將兩個陣列並起來。如果在並的過程中發現有兩個元素...

Java之Java中的變數 書(P23)

變數的定義 變數 儲存單元的名字 每乙個記憶體單元都用乙個識別符號來標識,這些記憶體單元被稱為變數,定義的識別符號就是變數名,記憶體單元儲存的資料就是變數的值。變數的型別轉換 1 自動型別轉換 隱式型別轉換 兩種型別在轉換過程中不需要顯示的進行宣告 兩種型別必須相容 目標型別的取值範圍大於原型別的取...