慢慢轉變思路,再也不死磕不會作的題,思路能夠先借鑑,可是必定要吃透透。
上週末看完看完了《算法圖解》,感受對一些題目的思路有比較大的幫助,可是仍是要在實踐中理解。算法
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
個人思路:
這題作了兩次,主體思路爲:每次都找到乘積中的最大正值
和最小負值
,由於絕對值最大的兩個數在下一次計算中才有可能成爲最大值。(畢竟題目沒有限制非負數)
第一次的時候報錯的緣由是,我記錄了每次的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
個人思路:
條件一:要判斷每次的值是否各位平方總和爲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)
個人思路:
這個算法借鑑了評論裏的一個炒雞有趣的算法,默認查詢是否質數的時候,咱們習慣用循環判斷,這樣確定會超時。
而這個算法呢,叫作厄拉多塞篩法
,他給了以下解釋:索引
好比說求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