1、买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
class Solution:
def maxProfit(self, prices: list[int]) -> int:
length = len(prices)
if len == 0:
return 0
have = [0] * length # 表示第i天持有股票所得最多现金
no = [0] * length # 表示第i天不持有股票所得最多现金
have[0] = -prices[0] # 此时的持有股票就一定是买入股票了
no[0] = 0 # 不持有股票那么现金就是0
for i in range(1, length):
have[i] = max(have[i - 1], -prices[i])
# have[i] = max(have[i-1], no[i-1] - prices[i]) (买卖股票的最佳时机2)
no[i] = max(no[i - 1], prices[i] + have[i - 1])
return no[-1]
if __name__ == '__main__':
solu = Solution()
prices = [7,1,5,3,6,4]
print(solu.maxProfit(prices))
2、买卖股票的最佳时机 2
给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格。
在每一天,你可能会决定购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以购买它,然后在 同一天 出售。
返回 你能获得的 最大 利润 。
示例 1:
输入: prices = [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
示例 2:
输入: prices = [1,2,3,4,5]
输出: 4
解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入: prices = [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
class Solution:
def maxProfit(self, prices: list[int]) -> int:
length = len(prices)
if len == 0:
return 0
have = [0] * length # 表示第i天持有股票所得最多现金
no = [0] * length # 表示第i天不持有股票所得最多现金
have[0] = -prices[0] # 此时的持有股票就一定是买入股票了
no[0] = 0 # 不持有股票那么现金就是0
for i in range(1, length):
# have[i] = max(have[i - 1], -prices[i]) (买卖股票的最佳时机1)
have[i] = max(have[i-1], no[i-1] - prices[i])
no[i] = max(no[i - 1], prices[i] + have[i - 1])
return no[-1]
if __name__ == '__main__':
solu = Solution()
prices = [7,1,5,3,6,4]
print(solu.maxProfit(prices))
3、买卖股票的最佳时机 3
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
示例 1:
输入:prices = [3,3,5,0,0,3,1,4]
输出:6
解释:在第 4 天(股票价格 = 0)的时候买入,在第 6 天(股票价格 = 3)的时候卖出,这笔交易所能获得利润 = 3-0 = 3 。随后,在第 7 天(股票价格 = 1)的时候买入,在第 8 天 (股票价格 = 4)的时候卖出,这笔交易所能获得利润 = 4-1 = 3 。
示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这个情况下, 没有交易完成, 所以最大利润为 0。
示例 4:
输入:prices = [1]
输出:0
class Solution:
def maxProfit(self, prices: List[int]) -> int:
if len(prices) < 2 :
return 0
m = len(prices)
buy1 = [0] * m
sell1 = [0] * m
buy2 = [0] * m
sell2 = [0] * m
buy1[0]=buy2[0]= -prices[0]
sell1[0]=sell2[0] = 0
for i in range(1,m):
buy1[i] = max(buy1[i-1],-prices[i])
sell1[i] = max(sell1[i-1],buy1[i-1] + prices[i])
buy2[i] = max(buy2[i-1],sell1[i-1]-prices[i])
sell2[i] = max(buy2[i-1] + prices[i] , sell2[i-1])
return sell2[-1]
4、整数反转
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
class Solution:
def myAtoi(self, s: str) -> int:
s = s.lstrip()
res = ""
flag = False # 标记答案的正负
mark = False # 标记有没有数字被选取过了
tag = False # 标记有没有“+”、“-”被选取过了
for i in s:
if i.isdigit():
res += i
mark = True
elif i == "+":
if mark:
break
if tag:
return 0
tag = True
elif i == "-":
if mark:
break
if tag:
return 0
flag = True
tag = True
else:
break
if len(res) == 0:
return 0
else:
res = int(res)
if flag:
res = -res
if res > 2 ** 31 - 1:
return 2 ** 31 - 1
elif res < -2 ** 31:
return -2 ** 31
else:
return res
if __name__ == '__main__':
s = '+-12'
solu = Solution()
try:
print(solu.myAtoi(s))
except Exception as e:
print(e.args)
5、实现 Str()函数
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与 C 语言的 strstr() 以及 Java 的 indexOf() 定义相符。
示例 1:
输入:haystack = "hello", needle = "ll"
输出:2
示例 2:
输入:haystack = "aaaaa", needle = "bba"
输出:-1
示例 3:
输入:haystack = "", needle = ""
输出:0
class Solution:
def strStr(self, haystack: str, needle: str) -> int:
def strStr(self, haystack, needle):
a, b = len(needle), len(haystack)
if a == 0: return 0
# 1、求next数组
nxt = self.getnext(needle)
# 2、模式匹配
p = -1
for j in range(b):
while p >= 0 and needle[p + 1] != haystack[j]:
p = nxt[p]
if needle[p + 1] == haystack[j]:
p += 1
if p == a - 1:
return j - a + 1
return -1
# 求next数组
def getnext(self, needle):
nxt = [-1] * len(needle)
j = -1
for i in range(1, len(needle)):
while (j >= 0 and needle[j + 1] != needle[i]):
j = nxt[j]
if needle[j + 1] == needle[i]:
j += 1
nxt[i] = j
return nxt
if __name__ == '__main__':
s = "mississippi"
n = "issip"
solu = Solution()
try:
print(solu.strStr(s, n))
except Exception as e:
print(e.args)
6、外观数列
给定一个正整数 n ,输出外观数列的第 n 项。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。
你可以将其视作是由递归公式定义的数字字符串序列:
countAndSay(1) = "1"
countAndSay(n) 是对 countAndSay(n-1) 的描述,然后转换成另一个数字字符串。
前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
第一项是数字 1
描述前一项,这个数是 1 即 “ 一 个 1 ”,记作 "11"
描述前一项,这个数是 11 即 “ 二 个 1 ” ,记作 "21"
描述前一项,这个数是 21 即 “ 一 个 2 + 一 个 1 ” ,记作 "1211"
描述前一项,这个数是 1211 即 “ 一 个 1 + 一 个 2 + 二 个 1 ” ,记作 "111221"
要 描述 一个数字字符串,首先要将字符串分割为 最小 数量的组,每个组都由连续的最多 相同字符 组成。然后对于每个组,先描述字符的数量,然后描述字符,形成一个描述组。要将描述转换为数字字符串,先将每组中的字符数量用数字替换,再将所有描述组连接起来。
例如,数字字符串 "3322251" 的描述如下图:
示例 1:
输入:n = 1
输出:"1"
解释:这是一个基本样例。
示例 2:
输入:n = 4
输出:"1211"
解释:
countAndSay(1) = "1"
countAndSay(2) = 读 "1" = 一 个 1 = "11"
countAndSay(3) = 读 "11" = 二 个 1 = "21"
countAndSay(4) = 读 "21" = 一 个 2 + 一 个 1 = "12" + "11" = "1211"
class Solution:
def countAndSay(self, n: int) -> str:
pre = ''
cur = '1'
# 从第 2 项开始
for _ in range(1, n):
# 这里注意要将 cur 赋值给 pre
# 因为当前项,就是下一项的前一项。有点绕,尝试理解下
pre = cur
# 这里 cur 初始化为空,重新拼接
cur = ''
# 定义双指针 start,end
start = 0
end = 0
# 开始遍历前一项,开始描述
while end < len(pre):
# 统计重复元素的次数,出现不同元素时,停止
# 记录出现的次数,
while end < len(pre) and pre[start] == pre[end]:
end += 1
# 元素出现次数与元素进行拼接
cur += str(end - start) + pre[start]
# 这里更新 start,开始记录下一个元素
start = end
return cur
if __name__ == '__main__':
n = 4
solu = Solution()
try:
print(solu.countAndSay(n))
except Exception as e:
print(e.args)