吳軍《谷歌面試題:倒置英文句子》

吳軍《谷歌面試題:倒置英文句子》

問題是這麼說的:給你一個英語的語句,比如"London bridge is falling down",把它完全倒裝過來,“down falling is bridge London”,如何不使用額外的存儲空間完成這個倒裝過程?

通常學習計算機算法的人在解決這個問題時,首先會想到把這個句子切割成一個個單詞,然後把它們存到一個數組裏,數組的結構大致如下:
在這裏插入圖片描述
把這個數組順序存入,逆序取出來就可以完成語句倒裝的問題。當然,還有一個類似的辦法,就是把上面的單詞,一個個送入堆棧,記得堆棧的先進後出,後進先出性質,就可以利用這個數據結構完成句子的倒裝。

但是,這種算法要額外地使用存儲空間,因此不符合題目的要求。在面試時,我們一般會讓選擇了上述方法的候選人把他們的想法說完,這樣至少讓他們在心理上不至於感受到打擊,但是接下來我們會要求他們找出不使用額外內存空間的方法。

很多人想到的是把上面句子中的單詞前後對調。但這道題目的難點恰恰在於英語單詞的長度不同,如果不使用額外的空間,很難把不同長度的單詞對調。

學習計算機的人會想到記錄下來句子一頭一尾兩個單詞的長度,然後把長的那個單詞先挪開,短的那個填進長的單詞空出來的位置。

比如在上面的例子中,London這個詞比較長,down這個詞比較短,可以把London先挪出來,把down這個詞放到London的位置中,這是放得下的。但是這樣接下來的問題又來了,長的單詞London無法填入短的單詞down留出來的空位。

當然,有人會想,在短的單詞那邊再挪走一個詞,具體到上面的例子中,就是挪走falling,看看能否把長的單詞安置進去。在這個例子中是可以的。當然,實際情況可能會比這個複雜,有可能留出的空間還不夠,比如of the 這兩個單詞的長度加起來也沒有Chinese一個長。即便句子尾巴上兩個單詞的位置能夠放頭上的一個長的單詞,但也有可能挪出的空間太多了,這樣句子的頭上放不下兩個單詞,上面的例子就陷入了後一種情況。

我講到這裏,你可能已經糊塗了,這其實就對了,因爲我也沒有打算讓你聽懂,我囉哩囉嗦地講了這麼多,無非是想說,前後對調單詞這件事遠比我們想象的複雜得多,以至於這個看似合理的想法在計算機中幾乎無法實現。

在我考察Google候選人中,我大約向十幾個候選人問了這個問題,大約一半的人(10人左右)試圖採用頭尾單詞對調的方法,但是這10個人沒有一個人能夠寫出實現他們想法的程序,因爲他們都走進了死衚衕。

上面這種方法的問題在哪裏呢?其實最大的問題在於人會陷入自己固有的思維方式,或者說常人的思維。這道題目中,我們要求以單詞爲單元進行倒裝,單詞本身必須維持原狀,因此大家爲了滿足這一點要求,不敢把單詞打碎,搞亂。而用計算機解決這個問題的關鍵,又恰恰是要把單詞先搞亂,再規整起來。這道題最好的解法其實非常簡單,如果你已經想到了,恭喜你,如果還沒有,不妨花一分鐘聽我講一下,其實只需要捅破一層窗戶紙。

第一步,先將整個句子看成是一個完整的字符串,以字母爲單位頭尾對調,這樣上面的句子就變成了下面這樣一個亂七八糟的字符串:“nwod gnillaf si egdirb nodnoL”

上面這一串字,你可能根本看不懂,但是沒有關係。接下來我們再完成第二步,你就看清楚了。

第二步,把用空格分割的每一個字串以字母爲單位,頭尾對調。比如第一個字串是nwod,頭尾對調後是down,也就是原來句子中的最後一個單詞。第二個字串是gnillaf,字母頭尾對調後是falling,原來句子中倒數第二個單詞。這樣一個個地做,直到最後一個字串裏的字母對調完畢。這樣就得到了下面的倒裝句子:“down falling is bridge London.”

這個方法爲什麼能成功呢?

這個方法看起來十分簡單,但是有趣的是,面試Google的人有一半做不出這道題,要知道能夠到Google公司面試的,十份簡歷也未必能挑出一兩個人,並非等閒之輩。但是,囿於平時的思維定式,特別是不敢把整個句子變成無意義的字串,很多人想不到先要把整個句子變得無意義,才能得到的後面有意義的單詞。

方法一

  • 創建reverse01.py
"""
倒置英文句子
"""

source = "London bridge is falling down"
words = source.split(" ")
target = ""
for i in range(len(words) - 1, -1, -1):
    target = target + words[i]
    if i > 0:
        target = target + " "
    
print(source)
print(target)

  • 運行程序,查看結果
    在這裏插入圖片描述

方法二

  • 創建reverse02.py
"""
倒置英文句子
"""

def reverse(source):
    source = list(source)
    length = len(source)
    for i in range(length // 2):
        source[i], source[length - i - 1] = source[length - i - 1], source[i]
    return ''.join(source)

if __name__ == '__main__':
    source = "London bridge is falling down"
    print(source)
    temp = reverse(source)
    print(temp)
    for word in temp.split(' '):
        print(reverse(word), end=' ')   
  • 運行程序,查看結果
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章