赞
踩
最近又开始刷题了(狗头保命),主要是补之前没做完的。
给定一个整数数组 nums
,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。
- 输入: [2,3,-2,4]
- 输出: 6
- 解释: 子数组 [2,3] 有最大乘积 6。
思路:
用两个dp数组,其中f[i]表示子数组[0, i]范围内的最大子数组乘积,g[i]表示子数组[0, i]范围内的最小子数组乘积,初始化时f[0]和g[0]都初始化为nums[0],其余都初始化为0。那么从数组的第二个数字开始遍历,那么此时的最大值和最小值只会在这三个数字之间产生,即f[i-1]*nums[i],g[i-1]*nums[i],和nums[i]。所以我们用三者中的最大值来更新f[i],用最小值来更新g[i],然后用f[i]来更新结果res即可。
注意负负得正,使用dp_min和dp_max分别保存到i为止连续子序列乘积的最大值和最小值,状态转移公式:
- dp_min[i] = min(dp_min[i - 1] * nums[i], dp_max[i - 1] * nums[i], nums[i])
- dp_max[i] = max(dp_min[i - 1] * nums[i], dp_max[i - 1] * nums[i], nums[i])
- class Solution(object):
- def maxProduct(self, nums):
- """
- :type nums: List[int]
- :rtype: int
- """
- n = len(nums)
- max_list = [0 for _ in range(n)]
- min_list = [0 for _ in range(n)]
- max_list[0] = nums[0]
- min_list[0] = nums[0]
- res = nums[0]
-
- for i in range(1, n):
- max_list[i] = max(max_list[i - 1] * nums[i], max(min_list[i - 1] * nums[i], nums[i]))
- min_list[i] = min(max_list[i - 1] * nums[i], min(min_list[i - 1] * nums[i], nums[i]))
- res = max(res, max_list[i])
-
- return res
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S。现在你有两个符号 + 和 -。对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面。
返回可以使最终数组和为目标数 S 的所有添加符号的方法数。
- 输入: nums: [1, 1, 1, 1, 1], S: 3
- 输出: 5
- 解释:
-
- -1+1+1+1+1 = 3
- +1-1+1+1+1 = 3
- +1+1-1+1+1 = 3
- +1+1+1-1+1 = 3
- +1+1+1+1-1 = 3
-
- 一共有5种方法让最终目标和为3。
思路
- class Solution:
- def findTargetSumWays(self, nums: List[int], S: int) -> int:
- sum_n = sum(nums)
- if (sum_n+S)%2!=0 or sum_n<S:
- return 0
- return self.sub_set(nums,(S+sum_n)//2)
-
- def sub_set(self,nums,S):
- dp = [0]*(S+1)
- dp[0] = 1
- for num in nums:
- #每一遍循环得到和值为i的方法数,以次更新
- for i in range(S,num-1,-1):
- dp[i] += dp[i-num]
- return dp[S]
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。