演算法練習:兩數之和,演算法兩數之和

來源:互聯網
上載者:User

演算法練習:兩數之和,演算法兩數之和

題目:給定一個整型數組,是否能找出兩個數使其和為指定的某個值?註:整型數組中不存在相同的數。

一、解題方法

1、暴力破解法(時間複雜度O(n^2) )

這是最容易想到的一種方法,即使用兩層迴圈,從數組裡取出一個數,然後在此數之後部分找出另外一個數,計算兩數之和,判斷是否等於指定值。如下:

//直觀的辦法,使用兩個迴圈bool IsExistSumOfTwoNum( int nArray[], int nCount, int nSum ){bool bRet = false;for ( int i = 0; i < nCount - 1; ++i ){for ( int j = i + 1; j < nCount; ++j ){if ( ( nArray[i] + nArray[j] ) == nSum ){bRet = true;break;}}}return bRet;}

此種方法的的時間複雜度為O(n^2),那麼能否降低此複雜度呢?答案是可以的,請看第二種方法。

 

2、排序加首尾指標(時間複雜度O(nlogn) )

先對數組進行從小到大的排序,然後設定首尾指標,從首尾兩端開始移動,一次移動一端的指標,直至兩指標相遇或者兩指標指向的數的和為指定的值。

假設兩指標為i,j,其中i < j,如果a[i]、a[j]之和大於指定值,那麼要找的兩個數一定在j的左側,如果a[i]、a[j]之和小於指定值,那麼要找的兩個數一定在i的右側。可用反證法證明此結論的正確性,證明略。

bool IsExistSumOfTwoNum( int nArray[], int nCount, int nSum ){//從小到大排序std::sort( nArray, nArray+nCount, std::less<int>() );//首尾指示int i = 0; int j = nCount - 1;bool bRet = false;while( i < j ){if ( ( nArray[i] + nArray[j] ) == nSum ){bRet = true;break;}else if ( ( nArray[i] + nArray[j] ) > nSum  ){--j;}else{++i;}}return bRet;}

此種演算法中,一開始有一個排序,最好的排序的時間複雜度可為O(nlogn),比如堆排序、歸併排序、快速排序。While迴圈至多掃描一遍數組,所以其時間表複雜度為O(n)。由此可得,最終的時間複雜度為O(nlogn)。那麼能否再降低時間複雜度呢?答案還是可以的,但是這時需要一個額外的儲存空間,請看第三種方法。

 

3、利用雜湊表(時間複雜度O(n) )

將複雜度為O(nlogn)降低至O(n),首先想到的是雜湊表,因為雜湊表的尋找時間複雜度為O(n)。

掃描一遍數組,將其數組各個值儲存至雜湊表中,比如鍵值:<數組值--索引>。然後再次開始從頭掃描數組,檢查指定值與當前值的差值是否在雜湊表中(特殊情況:如果遇到差值為當前值時,那麼不應返回,因為數組中的值是不相同的)。

程式碼實現說明:程式中使用c++標準庫中的set代替雜湊表,因為標準庫中還未收錄雜湊表相關部分。此處若需要兩數的索引資訊,可以考慮使用map。因為set、map內部使用的是紅/黑樹狀結構資料結構,尋找效率高,具體的複雜度,我還沒好好研究,呵呵。希望此處用set代替雜湊表,不要引起誤會,姑且將它理解為尋找複雜度為常數時間的東西吧。

 

//使用額外的儲存空間bool IsExistSumOfTwoNum( int nArray[], int nCount, int nSum ){//打描一遍數組,將值存放於雜湊表中//(註:此處使用set代替下雜湊表,它內部實現說是紅/黑樹狀結構,還沒仔細研究過,呵)std::set<int> siSetTemp;int i = 0;bool bRet = false;for ( i = 0; i < nCount; ++i ){siSetTemp.insert( nArray[i] );}for ( i = 0; i < nCount; ++i ){std::set<int>::iterator it = siSetTemp.find( nSum - nArray[i] );if ( it != siSetTemp.end() && (nSum != 2 * nArray[i] ) ){bRet = true;break;}}return bRet; }


此種演算法中,雜湊表的尋找是常數時間,所以時間複雜度為O(n),空間複雜度為

O(n),即數組大小O(n)。

 

二、擴充問題

如果要返回其中所有的可能或者數組裡面存在相同的數,那麼應當怎麼解決呢?相信有了以上的知識,這個解決起來也不難。一個是開闢一個儲存結果的數組,搜尋完整個數組空間;另外一個無非就是讓雜湊表中多存放點資料。



系列文章說明:
1.本系列文章[演算法練習],僅僅是本人學習過程的一個記錄以及自我激勵,沒有什麼說教的意思。如果能給讀者帶來些許知識及感悟,那是我的榮幸。
2.本系列文章是本人學習陳東鋒老師《進軍矽谷,程式員面試揭秘》一書而寫的一些心得體會,文章大多數觀點均來自此書,特此說明!
3.文章之中,難免有諸多的錯誤與不足,歡迎讀者批評指正,謝謝.


作者:山丘兒
轉載請標明出處,謝謝。原文地址:http://blog.csdn.net/s634772208/article/details/46388789


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.