######################## 买卖股票的最佳时机 ########################################3
def max_profix(nums):
n = len(nums)
res = 0
for i in range(n):
for j in range(i, n):
res = max(res, nums[j] - nums[i])
return res
def max_profix1(nums):
res = 0
buy = nums[0]
for i in nums:
if i < buy:
buy = i
res = max(i - buy, res)
return res
print(max_profix1([7, 6, 4, 3, 1]))
########################## 判断子序列 ############################################
def isSubsequence(s: str, t: str) -> bool:
location = -1
for i in s:
location = t.find(i, location + 1)
if location == -1:
return False
return True
def isSubsequence1(s: str, t: str) -> bool:
t = iter(t)
return all([i in t for i in s])
# print(isSubsequence1('abc', 'ahgdcb'))
############################## 打家劫舍 #######################################33
def rob(nums):
n = len(nums)
dp = [0] * n
dp[0] = nums[0]
dp[1] = max(dp[0], nums[1])
for i in range(2, n):
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
return dp[-1]
def rob1(nums):
pre, cur = 0, 0
for i in nums:
pre, cur = cur, max(cur, pre + i)
return cur
########################## 最大回文字串 ###########################################
def longestPalindrome(s: str) -> str:
n = len(s)
if n < 2:
return s
max_len = 1
begin = 0
# dp[i][j] 表示 s[i..j] 是否是回文串
dp = [[False] * n for _ in range(n)]
for i in range(n):
dp[i][i] = True
# 递推开始
# 先枚举子串长度
for L in range(2, n + 1):
# 枚举左边界,左边界的上限设置可以宽松一些
for i in range(n):
# 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
j = L + i - 1
# 如果右边界越界,就可以退出当前循环
if j >= n:
break
if s[i] != s[j]:
dp[i][j] = False
else:
if j - i < 3:
dp[i][j] = True
else:
dp[i][j] = dp[i + 1][j - 1]
# 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
if dp[i][j] and j - i + 1 > max_len:
max_len = j - i + 1
begin = i
return s[begin:begin + max_len]
print(longestPalindrome('cbaabdhhc'))
########################## 最大子数组和 ###############################
def max_sub_array(nums):
'''
暴力解法
第二层在第一层的基础上循环
:param nums:
:return:
'''
n = len(nums)
result = nums[0]
for i in range(n):
_sum = 0
for j in range(i, n):
_sum += nums[j]
result = max(result, _sum)
return result
def max_sub_array1(nums):
'''
动态规划
:param nums:
:return:
'''
n = len(nums)
pre = 0
res = nums[0]
for i in range(n):
pre = max(nums[i], pre + nums[i])
res = max(pre, res)
return res
def max_sub_array2(nums):
'''
贪婪算法,顺便找出子数组位置
:param nums:
:return:
'''
start = 0
end = 0
res = nums[0]
pre = 0
for i, value in enumerate(nums):
pre += value
if pre >= res:
res = pre
end = i
if pre < 0:
pre = 0
start = i + 1
return nums[start:end + 1], sum(nums[start:end + 1])
##################### 最长系列 #########################################
def longestPalindrome(s) -> int:
'''
给定一个包含大写字母和小写字母的字符串s,返回通过这些字母构造成的最长的回文串
在构造过程中,请注意区分大小写 。比如"Aa"不能当做一个回文字符串。
示例 1:
输入:s = "abccccdd"
输出:7
解释:
我们可以构造的最长的回文串是"dccaccd", 它的长度是 7。
输入:s = "a"
输入:1
'''
from collections import Counter
c = Counter(s)
res = 0
single = False
for i in c.values():
if i % 2 == 0:
res += i
else:
if not single:
res += 1
single = True
res += (i - 1)
return res
# print(longestPalindrome("abccccdd"))
def longestCommonPrefix(strs: list) -> str:
"""
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串""。
示例 1:
输入:strs = ["flower","flow","flight"]
输出:"fl"
示例 2:
输入:strs = ["dog","racecar","car"]
输出:""
解释:输入不存在公共前缀。
"""
base = strs[0]
others = strs[1:]
end = None
n = len(base)
for i in range(n):
if all([base[:i + 1] == j[:i + 1] for j in others]):
end = i + 1
else:
break
if end is not None:
return base[:end]
else:
return ''
def longestCommonPrefix1(strs: list) -> str:
if not strs:
return ""
print(sorted(strs))
str0 = min(strs)
str1 = max(strs)
for i in range(len(str0)):
if str0[i] != str1[i]:
return str0[:i]
return str0
# print(longestCommonPrefix1(["flower","flow","flight"]))
def findLength(A: list, B: list) -> int:
def maxLength(addA: int, addB: int, length: int) -> int:
ret = k = 0
for i in range(length):
if A[addA + i] == B[addB + i]:
k += 1
ret = max(ret, k)
else:
k = 0
return ret
n, m = len(A), len(B)
ret = 0
for i in range(n):
length = min(m, n - i)
ret = max(ret, maxLength(i, 0, length))
for i in range(m):
length = min(n, m - i)
ret = max(ret, maxLength(0, i, length))
return ret
def find_length(nums1, nums2):
m, n = len(nums1), len(nums2)
dp = [[0] * (m + 1) for i in range(n + 1)]
res = 0
for i in range(n - 1, -1, -1):
for j in range(m - 1, -1, -1):
dp[i][j] = dp[i + 1][j + 1] if nums1[i] == nums2[j] else 0
res = max(res, dp[i][j])
print(findLength([1, 2, 3, 2, 1], [3, 2, 1, 4, 7]))
########################### 爬楼梯 #####################################
def climb_stairs(n):
dp = [0] * (n + 1)
dp[0] = 1
dp[1] = 2
for i in range(2, n):
dp[i] = dp[i - 2] + dp[i - 1]
return dp[n - 1]
def climb_stairs1(n):
if n <= 2:
return n
return climb_stairs1(n - 1) + climb_stairs1(n - 2)
def climb_stairs1_1(n):
mem = [0] * (n + 1)
# 记忆化递归
def dfs(n):
if n <= 2:
return n
if mem[n] == 0:
mem[n] = climb_stairs1_1(n - 1) + climb_stairs1_1(n - 2)
return mem[n]
return dfs(n)
def climb_stair2(n):
pre, cur = 1, 1
for i in range(2, n + 1):
pre, cur = cur, pre + cur
return cur
print(climb_stair2(4))
# ######################## 使用最小花费爬楼梯 #############################
def min_cost_climb_stairs1(cost: list):
n = len(cost)
dp = [0] * n
dp[1] = min(cost[0], cost[1])
for i in range(2, n):
dp[i] = min(dp[i - 2] + cost[i - 1], dp[i - 1] + cost[i])
return dp[-1]