算法&&八股文&&其他
一、算法篇
- 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0
分析:简单题(lc121)
思路一动态规划 :根据题目意思,有以下两个约束条件:
条件 1:你不能在买入股票前卖出股票;
条件 2:最多只允许完成一笔交易。
当天是否持股 是一个很重要的因素,而当前是否持股和昨天是否持股有关系,为此我们需要把 是否持股 设计到状态数组中思路二记录历史最低点:
1、使用变量记录历史最低价格 minprice
2、则在第 i 天卖出股票能得到的利润就是 prices[i] - minprice
3、因此,我们只需要遍历价格数组一遍,记录历史最低点
class Solution_dp:
def maxProfit(self , prices ):
maxprofit = 0
dp = 0 #dp记为第i天卖出所获最大收益
for i in range(1,len(prices)):
dp = max(dp, 0) + prices[i]-prices[i-1] #则dp[i+1]=max(prices[i+1]-prices[i]+dp[i],prices[i+1]-prices[i])
if dp > maxprofit:
maxprofit = dp
return maxprofit
# write code here
class Solution_histMin:
def maxProfit(self , prices ):
# write code here
# 初始化最大值
inf = int(1e9)
minprice = inf
maxprofit = 0
for price in prices:
maxprofit = max(price - minprice, maxprofit)
# 找到最低股票价格
minprice = min(price, minprice)
return maxprofit
- 输入一个整型数组,数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值
分析:简单题(lc53)
动态规划 :dp[i]表示以i结尾的连续子数组的最大和。所以最终要求dp[n-1] 状态转移方程:dp[i] = max(array[i], dp[i-1]+array[i])
# -*- coding:utf-8 -*-
#空间优化为O(1)
class Solution:
def FindGreatestSumOfSubArray(self, array):
temp = array[0]
res = temp
for i in range(1, len(array)):
temp = max(temp, 0) + array[i]
if res < temp: res = temp
return res
# write code here
- 给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。
分析:hard(lc72)
dp(i, j)为str1[0…i]和str2[0…j]字符串为了匹配做出的代价
初始状态:dp[i][0] = i,i次删除;dp[0][i] = i,i次插入
转移方程:
当i字符等于j字符时:dp[i][j] = dp[i-1][j-1],不需要额外操作
当i字符不等于j字符时:dp[i][j] = Math.min(insert, delete, replace),其中
insert = dp[i][j-1] + 1; i个编辑成j-1个字符,再插入一个j
delete = dp[i-1][j] + 1; i-1个编辑成j个字母,再删除一个i
replace = dp[i-1][j-1] + 1; i-1个编辑成j-1个字母,再将i替换成j
# min edit cost
# @param str1 string字符串 the string
# @param str2 string字符串 the string
# @param ic int整型 insert cost
# @param dc int整型 delete cost
# @param rc int整型 replace cost
# @return int整型
#
class Solution:
def minEditCost(self , str1 , str2 , ic , dc , rc ):
lenth1, lenth2 = len(str1), len(str2)
dp = [[0] * (lenth2+1) for i in range(lenth1+1)]
for i in range(1, lenth1+1):
dp[i][0] = i * dc
for j in range(1, lenth2+1):
dp[0][j] = j * ic
for i in range(1, lenth1+1):
for j in range(1, lenth2+1):
#对str1的最后一个位置的最后一次操作分类讨论
if str1[i-1] == str2[j-1]: dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i-1][j-1] + rc, dp[i-1][j] + dc, dp[i][j-1] + ic)
return dp[-1][-1]
# write code here
二、八股文
- docker镜像和容器的区别及docker命令 (1, 2, 3)
- RNN梯度消失问题(1, 2, 3)
- svm相比于LR或者Perceptron的优势(1, 2)
- L1正则和L2正则(1)
- GPT和bert间主要的区别(1, 2)
- 生成式模型判别式模型有什么区别(1, 2)
- 模型的方差和偏差(1, 2, 3, 4)
三、其他
待解决 (欢迎评论区或私信解答)
-
给出一个有序数组A和一个常数C,求所有长度为C的子序列中的最大的间距D。
一个数组的间距的定义:所有相邻两个元素中,后一个元素减去前一个元素的差值的最小值. 比如[1,4,6,9]的间距是2.
例子:A:[1,3,6,10], C:3。最大间距D应该是4,对应的一个子序列可以是[1,6,10]。 -
给定一个数字矩阵和一个数字target,比如5。从数字1开始(矩阵中可能有多个1),每次可以向上下左右选择一个方向移动一次,可以移动的条件是下个数字必须是上个数字+1,比如1必须找上下左右为2的点,2必须找上下左右为3的点,以此类推。求到达target一共有几个路径。