這個題集後面的內容都是dp,頭疼。
1.輸入n個整數,輸出最小的k個
solution-1: 先排序後輸出o(nlogn)//快速排序複雜度
solution-2:把陣列分為length=k, length=n-k兩部分,通過比較大小來做//o(n*k)
solution-3:用堆來處理o(n*logk)
further:
谷歌面試題:輸入是兩個整數陣列,他們任意兩個數的和又可以組成乙個陣列,求這個和中前k個數怎麼做?
似乎沒有辦法,最壞的情況只有是在
必須要對兩個陣列分別排序。
2.尋找和為定值的兩個數
輸入乙個陣列和乙個數字,在陣列中查詢兩個數,使得它們的和正好是輸入的那個數字。
要求時間複雜度是o(n)。如果有多對數字的和等於輸入的數字,輸出任意一對即可。
例如輸入陣列1、2、4、7、11、15和數字15。由於4+11=15,因此輸出4和11。
solution-1: 已知需要的和15,做減法得到所需差值陣列14、13、11、8、4、0
2.2 尋找和為定值的兩個數 | 程式設計之法:面試和演算法心得wizardforcel.gitbooks.io
我覺得這個說法有問題,題目又沒說陣列有序,加上排序就不止o(n)了,而是o(nlogn)
solution-2: hash,構造hash表
分析:這類題就是排序與選擇演算法的問題
3.尋找和為定值的多個數
輸入兩個整數n和sum,從數列1,2,3.......n 中隨意取幾個數,使其和等於sum,要求將其中所有的可能組合列出來。
分析:不定個數就可以思考一下tree,毫無疑問decision tree+pruning是可以奏效的,但有點花時間調**,也不高效。
這道題同時也可視為 01揹包問題的變種
不要gakki也要學會的:動態規劃(dp)問題解析www.jianshu.com
不同於我們文中提到的最小張鈔票湊錢,或者最大價值裝揹包的問題,我們現在要窮舉出所有的可能組合,而不是最值組合。
感覺狀態轉移方程一對多就不叫狀態轉移方程了,類似於人工智慧裡面的inital state發展的問題。
inital state -> serval states:->...
4.最大連續子陣列和
輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。 求所有子陣列的和的最大值,要求時間複雜度為o(n)。
例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5
,和最大的子陣列為3, 10, -4, 7, 2
, 因此輸出為該子陣列的和18。
這道題的難點在於,你不可能把負元素直接剔除掉,例如-4的左右分別是10和7,這個-4多半是會被計算到鄰近的子陣列裡的。
無疑可以用dp來解了,畢竟有了最大這個最值條件,我們就可以列出正常的狀態轉移方程。
我們用d(i)來表示以l[i]結尾的子陣列的最大和,那麼有:
d(0)=1
d(1)=max=1
d(2)=?
這裡就要注意了,顯然我們的狀態轉移方程走不通,不適用於l[i-1]為負數並且d(i-1)沒有加入l[i-1]的情況
那麼當前的狀態轉移方程是不對的,我們應該分寫成條件分段函式
分析:為啥要用i結尾的子陣列最大和來處理問題?因為我們需要的是全域性子陣列最大和,要簡化問題,就要找到突破口,如果是子陣列和,顯然是不行的,因為我們沒法判斷是不是中間出現乙個負數應該中斷。
在要求f(i)必然和f(i-1)有關的情況下,可以聯想到以下標作為開頭或者結尾,姑且我們以下標作為結尾。
這樣問題就變成了,是不是要在l[i]的基礎上加入前面的子陣列。
5.跳台階問題
乙個台階總共有n 級,如果一次可以跳1 級,也可以跳2 級。
求總共有多少總跳法,並分析演算法的時間複雜度。
分析:這是一道簡單地dp問題
設剩餘台階數為i,一共的跳法為d(i)
那麼:d(1)=1//就只能跳一步
d(2)=2//1+1 or 2
d(3)=3//1+1+1 or 1+2 or 2+1
d(4)=5//2+2 or 1+1+1+1 or 2+1+1 or 1+2+1 or 1+1+2
d(i)=d(i-1)+d(i-2)
這似乎也可以用於求解n天後學校食堂的斐波那契湯問題...
既然有了狀態轉移方程,我們可以輕易得到結果
6.奇偶排序
輸入乙個整數陣列,調整陣列中數字的順序,使得所有奇數字於陣列的前半部分,所有偶數字於陣列的後半部分。要求時間複雜度為o(n)。
solution-1: 兩個指標,乙個從頭開始,乙個從尾部開始,從頭開始的遇到偶數字就停住,從尾開始的遇到奇數字就停住,如果兩個指標都停住時,交換兩個slot的值,繼續向中間匯合,匯合之後,演算法結束。
時間複雜度o(n)
這是塊排partition操作的變種(invisible midium)
7.荷蘭國旗問題
pass
8.矩陣相乘
請程式設計實現矩陣乘法,並考慮當矩陣規模較大時的優化方法
strassen乘法應該看看這篇文章,敘述很清晰文筆很好,都可以用作講義了
矩陣乘法strassen演算法www.jianshu.com
練習題部分:
9.不用除法運算
兩個陣列a[n],b[n],其中a[n]的各個元素值已知,現給b[i]賦值,b[i] = a[0]a[1]a[2]...*a[n-1]/a[i]; 要求:
記left[i]=∏a[k], (k=1...i-1); right=∏a[k], (k=i+1...n),根據題目描述b[i]=left[i] * right[i], 對於每乙個b[i]初始化為1,left[i]和right[i]兩部分可以分開兩次相乘,即對於迴圈變數i=1...n, b[i]=left[i];b[n-i]=right[n-i], 迴圈完成時即可完成計算。
解析:這道題其實是考對procedural language的較深理解。
要知道不是所有語言都是有state的,比如prolog。
既然有state,我們不妨吧b[i]看做乙個state在記憶體中的變數,也就是乙個狀態(這句話可以跳過)
分成兩部分,0..i-1, n..i+1,先順序更新每個b[i]到
同理,倒序更新每個b[i]*=
大功告成。
10.找出陣列中唯一重複元素
1-1000放在含有1001個元素的陣列中,只有唯一的乙個元素值重複,其它均只出現一次。 每個陣列元素只能訪問一次,設計乙個演算法,將它找出來;不用輔助儲存空間,能否設計乙個演算法實現?
分析:這題唯一的考點就是不用輔助儲存空間
soultion1: 暴力解法毫無疑問是輪詢,比較i和其他index有沒有值相同,這樣是
solution2:根據題目中特定條件,1-1000,只有唯一元素重複
int ret = sum(array)-sum(1..1000),
solution3:利用
可求出大部分元素重複兩次陣列中僅出現一次的乙個數
對於這道題,我們需要的是唯一重複的這個元素,顯然我們需要拼湊乙個1..1000到異或中去,就能得到奇數個異或1個,這個數即使return值
11.找出陣列中僅有的三個重複元素
乙個陣列裡,數都是兩兩出現的,但是有三個數是唯一出現的,找出這三個數。
找出陣列中單獨出現的3個數 - weixin_34162228的部落格 - csdn部落格blog.csdn.net
12.找出反序的個數
給定一整型陣列,若陣列中某個下標值大的元素值小於某個下標值比它小的元素值,稱這是乙個反序。 即:陣列a; 對於i < j 且 a[i] > a[j],則稱這是乙個反序。 給定乙個陣列,要求寫乙個函式,計算出這個陣列裡所有反序的個數。
組合多個陣列
function joinresult result,main key result key value key arr a1 array array 0 1 org id 10 new customers 100 new orders 100 array 0 2 org id 20 new cus...
數字,陣列,字串
例項 include using namespace std intmain 序號函式 描述 1double cos double 該函式返回弧度角 double 型 的余弦。2double sin double 該函式返回弧度角 double 型 的正弦。3double tan double 該函...
求乙個數字陣列裡的最大連續數字的個數
問題 求乙個數字陣列裡的最大連續數字的個數。比如 3,4,4,4,2,2,3,4 return 3。此題為google的面試題。分析 設定兩個變數 全域性最大連續數字個數 maxsucc 以及區域性連續數字個數 temp。從第二個數字開始,如果當前數字比前乙個數字大1,則 temp 遇到不滿足條件的...