小李飛刀:作題第八彈!

寫在前面的話

慢慢轉變思路,再也不死磕不會作的題,思路能夠先借鑑,可是必定要吃透透。
上週末看完看完了《算法圖解》,感受對一些題目的思路有比較大的幫助,可是仍是要在實踐中理解。算法

認真作題的分割線

第一題

152. 乘積最大子序列
難度:中等
給定一個整數數組nums,找出一個序列中乘積最大的連續子序列(該序列至少包含一個數)。
個人題解:數組

class Solution(object):
    def maxProduct(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        length = len(nums)
        maxsum = [0 for _ in range(length)]
        minsum = [0 for _ in range(length)]
        maxsum[0] = minsum[0] = nums[0] # 限定最大最小值
        dp = nums[0] #當前狀態
        for i in range(1,len(nums)):
            maxsum[i] = max(maxsum[i-1]*nums[i],minsum[i-1]*nums[i],nums[i])
            minsum[i] = min(maxsum[i-1]*nums[i],minsum[i-1]*nums[i],nums[i])
            dp = max(dp,maxsum[i])
        return dp

clipboard.png

個人思路:
這題作了兩次,主體思路爲:每次都找到乘積中的最大正值最小負值,由於絕對值最大的兩個數在下一次計算中才有可能成爲最大值。(畢竟題目沒有限制非負數)
第一次的時候報錯的緣由是,我記錄了每次的maxsum和minsum,沒有記錄上一次循環留下的值。
然鵝,上一次的狀態會影響到下一次的狀態,因此必須記住上一步的最優解。
能夠判斷是個NP問題,可是動態規劃還得多多練習app

第二題

202. 快樂數
難度:簡單
編寫一個算法來判斷一個數是否是「快樂數」。spa

一個「快樂數」定義爲:對於一個正整數,每一次將該數替換爲它每一個位置上的數字的平方和,而後重複這個過程直到這個數變爲 1,也多是無限循環但始終變不到 1。若是能夠變爲 1,那麼這個數就是快樂數。
個人題解:3d

class Solution(object):
    def isHappy(self, n):
        """
        :type n: int
        :rtype: bool
        """
        l = []
        while 1:
            l.append(n)
            n = sum([int(i)**2 for i in str(n)])
            if n == 1:
                return True
            elif n in l:
                return False

clipboard.png

個人思路:
條件一:要判斷每次的值是否各位平方總和爲1,得出是快樂數的結論;
條件二:爲了得出非快樂數的結論,這個數可能會陷入循環,那麼就要記錄下每輪的值,並進行比對。
其餘:
在評論中發現了一個頗有趣的算法,就是用dict記錄下確定會循環的數字的詞典,當遇到相關數字的時候就能夠跳出了。
通常爲{4,16,37,58,89,145,42,20}code

第三題

204. 計數質數
難度:簡單
統計全部小於非負整數 n 的質數的數量。
個人題解:blog

class Solution(object):
    def countPrimes(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n < 3:
            return 0
        else:
            output = [1]*n
            output[0],output[1] = 0,0
            for i in range(2,int(n**0.5+1)):
                if output[i] == 1:
                    m = i**2
                    while m < n:
                        output[m] = 0
                        m += i
        return sum(output)

clipboard.png

個人思路:
這個算法借鑑了評論裏的一個炒雞有趣的算法,默認查詢是否質數的時候,咱們習慣用循環判斷,這樣確定會超時。
而這個算法呢,叫作厄拉多塞篩法,他給了以下解釋:索引

好比說求20之內質數的個數,首先0,1不是質數.2是第一個質數,而後把20之內全部2的倍數劃去.2後面緊跟的數即爲下一個質數3,而後把3全部的倍數劃去.3後面緊跟的數即爲下一個質數5,再把5全部的倍數劃去.以此類推

包括他的題解的寫法也頗有趣,可是我還沒弄明白
output[i*i:n:i] = [0] * len(output[i*i:n:i])這一句的意思,還要琢磨下,因此用的是循環的寫法。ip

def countPrimes(self, n: int) -> int:
        if n < 3:
            return 0     
        else:
            # 首先生成了一個所有爲1的列表
            output = [1] * n
            # 由於0和1不是質數,因此列表的前兩個位置賦值爲0
            output[0],output[1] = 0,0
             # 此時從index = 2開始遍歷,output[2]==1,即代表第一個質數爲2,而後將2的倍數對應的索引
             # 所有賦值爲0. 此時output[3] == 1,即代表下一個質數爲3,一樣劃去3的倍數.以此類推.
            for i in range(2,int(n**0.5)+1): 
                if output[i] == 1:
                    output[i*i:n:i] = [0] * len(output[i*i:n:i])
         # 最後output中的數字1代表該位置上的索引數爲質數,而後求和便可.
        return sum(output)

總結

小李今天的作題,是痛並快樂着的!leetcode

相關文章
相關標籤/搜索