学习目标:
- 刷完面试经典150题
- 链接: 面试经典150题
学习内容:
-
- 买卖股票的最佳时机 II→贪心/数组/动态规划
-
- 跳跃游戏
-
- 旋转图像
-
- 合并区间
-
- 简化路径
-
- 两数相加
学习时间:
4.12
知识点
学习内容:
122. 买卖股票的最佳时机 II
给你一个整数数组 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 。
总利润为 4 + 3 = 7 。
示例 2:
输入:prices = [1,2,3,4,5] 输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 => 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
总利润为 4 。
示例 3:输入:prices = [7,6,4,3,1] 输出:0 解释:在这种情况下,
交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。
本题考虑贪心算法
我们想要的是摄取最高利益,也就是说,想法设法把股票在最低点买入,在最高点卖出。

根据图像进行理解,怎么判断是否当天要卖出股票呢?当然是从当天忘前一天看。如果当天股票大于前一天的股票,那么就选择在前一天买入,当天卖出(红色曲线部分);如果当年价格低于前一天的价格,则不进行操作。
这就是贪心算法,在每一步都选择利益最大的方式进行买卖。
代码如下
class Solution(object):
def maxProfit(self, prices):
"""
:type prices: List[int]
:rtype: int
"""
n=len(prices)
sum=0
if n==1:
return 0
for i in range(1,n):
if prices[i]-prices[i-1]>0:
sum+=prices[i]-prices[i-1]
return sum
if __name__ == "__main__":
s = Solution()
prices = [7,1,5,3,6,4]
print(s.maxProfit(prices))
55. 跳跃游戏
给你一个非负整数数组 nums ,你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个下标,如果可以,返回 true ;否则,返回 false 。
示例 1:
输入:nums = [2,3,1,1,4] 输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 1 跳 3
步到达最后一个下标。
示例 2:输入:nums = [3,2,1,0,4] 输出:false
解释:无论怎样,总会到达下标为 3 的位置。但该下标的最大跳跃长度是 0 ,
所以永远不可能到达最后一个下标。
思路:
每次都走最大的步数,也就是当前位置i+可走的最大步数nums[i]。如果碰到0,就进行回溯。
class Solution(object):
def canJump(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
n=len(nums)
if n==1:
return True
i=0
while i!=n-1:
i+=nums[i]
if i>=n-1:
return True
else:
if nums[i]==0:
j=1
while i-j>=0 and nums[i-j]+i-j<=i:
j+=1
if i-j==-1:
return False
else:
i=i-j
if __name__ == "__main__":
s=Solution()
nums = [3,2,1,0,4]
print(s.canJump(nums))
48. 旋转图像
给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。
你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。
示例 1:
输入:matrix = [[1,2,3],[4,5,6],[7,8,9]] 输出:[[7,4,1],[8,5,2],[9,6,3]]
示例 2:
输入:matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]]
输出:[[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]
矩阵先转置,再对称交换即可(即转置后,第一列和最后一列交换,第二列和倒数第二列交换。。。。。。)
import numpy as np
class Solution(object):
def rotate(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: None Do not return anything, modify matrix in-place instead.
"""
n = len(matrix[0])
for i in range(n):
for j in range(i,n):
matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j]
i=0
j=n-1
while i<j:
for k in range(n):
matrix[k][i],matrix[k][j]=matrix[k][j],matrix[k][i]
i+=1
j-=1
if __name__ == "__main__":
s=Solution()
matrix = [[1,2,3],
[4,5,6],
[7,8,9]]
print(s.rotate(matrix))
56. 合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:输入:intervals = [[1,4],[4,5]] 输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
先让数组按照第一列排序,这样就不用考虑合并区间的左侧的情况了。
建立ans用来保存区间
若ans为空,那么直接把区间加入ans
否则进行判断,是否最后加入ans数组区间的右侧大于当前遍历区间的左侧,若大于,则说明区间重合,需要进行合并操作。
绘制了散点图方便理解一些

class Solution(object):
def merge(self, intervals):
"""
:type intervals: List[List[int]]
:rtype: List[List[int]]
"""
ans=[]
n=len(intervals)
intervals=sorted(intervals,key=lambda x:x[0])
i=0
while i < n:
if len(ans)==0:
ans.append([intervals[i][0],intervals[i][1]])
else:
if ans[-1][1]>=intervals[i][0]:
ans[-1][1]=max(ans[-1][1],intervals[i][1])
else:
ans.append([intervals[i][0],intervals[i][1]])
i+=1
return ans
if __name__ == "__main__":
s=Solution()
intervals = [[1,3],[2,6],[8,10],[15,18]]
print(s.merge(intervals))
71. 简化路径
给你一个字符串 path ,表示指向某一文件或目录的 Unix 风格 绝对路径 (以 ‘/’ 开头),请你将其转化为更加简洁的规范路径。
在 Unix 风格的文件系统中,一个点(.)表示当前目录本身;此外,两个点 (…)
表示将目录切换到上一级(指向父目录);两者都可以是复杂相对路径的组成部分。任意多个连续的斜杠(即,‘//’)都被视为单个斜杠 ‘/’ 。
对于此问题,任何其他格式的点(例如,‘…’)均被视为文件/目录名称。请注意,返回的 规范路径 必须遵循下述格式:
始终以斜杠 ‘/’ 开头。 两个目录名之间必须只有一个斜杠 ‘/’ 。 最后一个目录名(如果存在)不能 以 ‘/’ 结尾。
此外,路径仅包含从根目录到目标文件或目录的路径上的目录(即,不含 ‘.’ 或 ‘…’)。 返回简化后得到的 规范路径 。示例 1:
输入:path = “/home/” 输出:“/home” 解释:注意,最后一个目录名后面没有斜杠。
示例 2:输入:path = “/…/” 输出:“/” 解释:从根目录向上一级是不可行的,因为根目录是你可以到达的最高级。
示例 3:输入:path = “/home//foo/” 输出:“/home/foo” 解释:在规范路径中,多个连续斜杠需要用一个斜杠替换。 示例
4:输入:path = “/a/./b/…/…/c/” 输出:“/c”
有一说一,这破题目够长的,但是题倒是不难熬
代码:
class Solution(object):
def simplifyPath(self, path):
"""
:type path: str
:rtype: str
"""
str1=[]
path=path.split('/')
path=[x for x in path if x!='' and x!='.'] #去除''元素
for i in path:
str1.append(i)
if i=='..':
str1.pop()
if len(str1)!=0:
str1.pop()
str1='/'+'/'.join(str1)
return str1
if __name__ == "__main__":
s=Solution()
path = "/a/./b/../../c/"
print(s.simplifyPath(path))
2. 两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例 1:
输入:l1 = [2,4,3], l2 = [5,6,4] 输出:[7,0,8] 解释:342 + 465 = 807.
示例 2:输入:l1 = [0], l2 = [0] 输出:[0] 示例 3:
输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9] 输出:[8,9,9,9,0,0,0,1]
简单题,考虑好进位就好啦!
# Definition for singly-linked list.
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution(object):
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
carry = 0
l_h=ListNode()
node=l_h
while l1 and l2:
node.next=ListNode(l1.val+l2.val+carry)
node=node.next
carry=0
if node.val>9:
carry=1
node.val=node.val%10
l1=l1.next
l2=l2.next
if l1:
while l1:
node.next=ListNode(l1.val+carry)
carry=0
node=node.next
if node.val>9:
carry=1
node.val=node.val%10
l1=l1.next
if l2:
while l2:
node.next=ListNode(l2.val+carry)
carry=0
node=node.next
if node.val>9:
carry=1
node.val=node.val%10
l2=l2.next
if carry==1:
node.next=ListNode(carry)
return l_h.next
if __name__ == "__main__":
s=Solution()
l1=ListNode(2)
l1.next = ListNode(4)
l1.next.next = ListNode(9)
l2=ListNode(5)
l2.next = ListNode(6)
l2.next.next = ListNode(4)
l2.next.next.next = ListNode(9)
# print(s.addTwoNumbers(l1,l2))
node=s.addTwoNumbers(l1,l2)
while node:
print(node.val)
node = node.next
最后成果
- 122. 买卖股票的最佳时机 II
- 55. 跳跃游戏
- 48. 旋转图像
- 56. 合并区间
- 71. 简化路径
- 2. 两数相加
结论
道友,加油!!
本文介绍了如何使用贪心算法解决买卖股票的最佳时机问题,以及涉及的其他技术点如链表操作(两数相加)、数组处理(跳跃游戏、旋转图像)、动态规划和区间合并。通过实例展示了如何在实际场景中应用这些算法解决问题。




被折叠的 条评论
为什么被折叠?



