Ugly Number

題目

給一個數判斷它是否是醜數。
說明:因子只包含2或3或5的數稱作醜數。假定1是醜數。

解題過程

如果給定一個數,判斷它是不是醜數很簡單,只需依次除以2, 3,5,然後分析最後的結果,就可知道它是不是醜數。

然後還有一個進階版,就是求醜數序列的第n個醜數。這個聽起來似乎很簡單的樣子,但是其實還暗藏玄機呢。我最開始的思路是依次求出前n個從醜數,這樣做的複雜度在O(n²),超過了所規定的時間複雜度。

接着,我試着去想是否可以把時間複雜度降到n,這樣就是說前後的醜數是有聯繫的。然後我試着想方法去找出醜數序列中序號和醜數的對應關係,結果並沒有找到。在斷斷續續地思考過程中,我隱約意識到可能存在着一種由前向後的迭代能夠實現在O(n)的複雜度計算出第n個醜數。然後我試圖找出計算醜數序列的累乘規律,但是從序列的前端元素來看,似乎很難發現什麼規律。

最後我看了看discussion發現支持率較高的java solution中採用了隊列,這是一種我並不怎麼熟悉的數據結構和類,一開始拿過代碼來,整個人就蒙了,根本不理解題目的意思。於是我就去搜索瞭解隊列和LinkedList兩種數據結構。查了查他們的主要方法,然後還是不懂它這是在幹什麼(智商拙計啊),於是我又查了查關於醜數解法的中文解析,才最終明白了它的算法的思想。

總結

java中有很多類和數據結構我都不瞭解,這對於最初的我來說,去思考這個題的答案確實有些高要求了。當時我有思路涉及到需要很多個2或3或5相乘,但是思路卻侷限於他們各自的個數,而非在可能的組合結果裏挑選出最小值。也許再繼續這麼想下去最後會貼近於正確的思路,但是同樣不知道Java裏有queue的類可以用來實現該題。

尋找共性:那麼我想,在使用queue結構的應用情境中,他們一定有很多共性。例如醜數這個題,我們維護三個隊列:

  • q2隊列中我們只進行*2的操作;
  • q3隊列中只進行*3的操作;
  • q5隊列中只進行*5的操作。
  • 然後我們始終取三個隊列中所出現的醜數的最小值,當然這三個隊列都是有序隊列。當然,還設置了一個變量res用來保存當前的第i個醜數。

    這種思路特別像是多線程問題,他們共同在處理一個res的資源。在滿足不同的條件下執行不同的操作。要注意到有一點思路很特別。就是之前思考問題,思路都是線性的,也就是單線程吧,不會橫向發散,例如採用多隊列的思想實現了多線程。

    反思

    時隔近一年之後,我在總結自己刷leetcode題目的過程。現在已經刷完了67道題,基本easy難度的題自己都能解決出來,但是多數耗時在一小時左右,曾經在網上看到帖子說要想進大公司,easy題目必須刷到能夠10-15分鐘一道,這說明即便是基礎題目,自己和較好的水平仍有較大差距。
    在今年六月份全職刷題以後,大約用了一個月的時間刷了60道題,多數題遵循儘量自己想的原則,實在想不出來的話去參考實現discuss的答案。回過頭來看醜數2這道題,題目難度是中等類型,用了三個隊列,當時剛開始刷題,對leetcode刷題的過程也沒啥概念,進度很慢,毫無頭緒。
    現在發現其實算法設計在很大程度上也依賴於自己對數據結構的掌握程度,只有非常熟練常用的數據結構,才能更好的更熟練的去構思設計基於某些數據結構的算法。
    所以應該去「刻意練習」java中的數據結構嗎?

    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章