程序员面试题精选100题(40)-扑克牌的顺子[算法]
題目:從撲克牌中隨機抽5張牌,判斷是不是一個順子,即這5張牌是不是連續(xù)的。2-10為數(shù)字本身,A為1,J為11,Q為12,K為13,而大小王可以看成任意數(shù)字。
?????????分析:這題目很有意思,是一個典型的寓教于樂的題目。
?????????我們需要把撲克牌的背景抽象成計算機語言。不難想象,我們可以把5張牌看成由5個數(shù)字組成的數(shù)組。大小王是特殊的數(shù)字,我們不妨把它們都當(dāng)成0,這樣和其他撲克牌代表的數(shù)字就不重復(fù)了。
?????????接下來我們來分析怎樣判斷5個數(shù)字是不是連續(xù)的。最直觀的是,我們把數(shù)組排序。但值得注意的是,由于0可以當(dāng)成任意數(shù)字,我們可以用0去補滿數(shù)組中的空缺。也就是排序之后的數(shù)組不是連續(xù)的,即相鄰的兩個數(shù)字相隔若干個數(shù)字,但如果我們有足夠的0可以補滿這兩個數(shù)字的空缺,這個數(shù)組實際上還是連續(xù)的。舉個例子,數(shù)組排序之后為{0,1,3,4,5}。在1和3之間空缺了一個2,剛好我們有一個0,也就是我們可以它當(dāng)成2去填補這個空缺。
?????????于是我們需要做三件事情:把數(shù)組排序,統(tǒng)計數(shù)組中0的個數(shù),統(tǒng)計排序之后的數(shù)組相鄰數(shù)字之間的空缺總數(shù)。如果空缺的總數(shù)小于或者等于0的個數(shù),那么這個數(shù)組就是連續(xù)的;反之則不連續(xù)。最后,我們還需要注意的是,如果數(shù)組中的非0數(shù)字重復(fù)出現(xiàn),則該數(shù)組不是連續(xù)的。換成撲克牌的描述方式,就是如果一副牌里含有對子,則不可能是順子。
?????????基于這個思路,我們可以寫出如下的代碼:
// Determine whether numbers in an array are continuous // Parameters: numbers: an array, each number in the array is between // 0 and maxNumber. 0 can be treeted as any number between // 1 and maxNumber // maxNumber: the maximum number in the array numbers bool IsContinuous(std::vector<int> numbers, int maxNumber) {if(numbers.size() == 0 || maxNumber <=0)return false;// Sort the array numbers.std::sort(numbers.begin(), numbers.end());int numberOfZero = 0;int numberOfGap = 0;// how many 0s in the array?std::vector<int>::iterator smallerNumber = numbers.begin();while(smallerNumber != numbers.end() && *smallerNumber == 0){numberOfZero++;++smallerNumber;}// get the total gaps between all adjacent two numbersstd::vector<int>::iterator biggerNumber = smallerNumber + 1;while(biggerNumber < numbers.end()){// if any non-zero number appears more than once in the array,// the array can't be continuousif(*biggerNumber == *smallerNumber)return false;numberOfGap += *biggerNumber - *smallerNumber - 1;smallerNumber = biggerNumber;++biggerNumber;}return (numberOfGap > numberOfZero) ? false : true; }?????????本文為了讓代碼顯得比較簡潔,上述代碼用C++的標(biāo)準(zhǔn)模板庫中的vector來表達數(shù)組,同時用函數(shù)sort排序。當(dāng)然我們可以自己寫排序算法。為了有更好的通用性,上述代碼沒有限定數(shù)組的長度和允許出現(xiàn)的最大數(shù)字。要解答原題,我們只需要確保傳入的數(shù)組的長度是5,并且maxNumber為13即可。
?
????本文已經(jīng)收錄到《劍指Offer——名企面試官精講典型編程題》一書中,有改動,書中的分析講解更加詳細。歡迎關(guān)注。
??????? 本題已被九度Online Judge系統(tǒng)收錄,歡迎讀者移步到http://ac.jobdu.com/hhtproblems.php在線測試自己的代碼。
??? 博主何海濤對本博客文章享有版權(quán)。網(wǎng)絡(luò)轉(zhuǎn)載請注明出處http://zhedahht.blog.163.com/。整理出版物請和作者聯(lián)系。
總結(jié)
以上是生活随笔為你收集整理的程序员面试题精选100题(40)-扑克牌的顺子[算法]的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员面试题精选100题(39)-颠倒栈
- 下一篇: 程序员面试题精选100题(43)-n个骰