慢慢转变思路,再也不死磕不会作的题,思路能够先借鉴,可是必定要吃透透。
上周末看完看完了《算法图解》,感受对一些题目的思路有比较大的帮助,可是仍是要在实践中理解。算法
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