11月1日 大数和中的极值位距离
问题描述
小R面对一个问题,她有两个由数字字符组成的超大字符串数,需要求出这两个数相加后得到的字符串数中的最大数和最小数之间的位数差距。如果结果中所有数字都相同,则差距为0。如果存在多个符合最大或最小条件的数,应该选择最小的位置差。
例如,字符串数“111"和“222"相加得到"333",所有数字相同,因此位数差为 0。另一例子,字符串数"111"和"34"相加得到"145",其中最大数是"5'位于第3位,最小数是"1'位于第1位,他们之间的位差为 1。
思考:
-
给定两个由数字字符组成的字符串,需要先将它们转换为整数并相加,然后将结果转回字符串。这样可以处理非常大的数字,避免溢出的问题。
-
在得到的结果字符串中,找到最大和最小的数字字符。然后,确定这些数字在字符串中的位置,并计算它们之间的位差。
-
如果最大数和最小数相等,说明结果中所有数字都是相同的,位数差为 0。
-
对于最大数和最小数,找出它们在字符串中的所有位置索引,计算这些位置之间的最小差值(即最小的位数差)。如果多个最大数或最小数存在,应该选择最小的位差。
代码:
def solution(string1, string2): # 将字符串转换为整数并进行加法 sum_result = str(int(string1) + int(string2)) # 查找最大数和最小数 max_digit = max(sum_result) min_digit = min(sum_result) # 如果最大数和最小数相等,返回 0 if max_digit == min_digit: return 0 # 找到所有最大数和最小数的索引 max_indices = [i for i, d in enumerate(sum_result) if d == max_digit] min_indices = [i for i, d in enumerate(sum_result) if d == min_digit] # 计算最小位数差 min_distance = min(abs(max_idx - min_idx) for max_idx in max_indices for min_idx in min_indices) return min_distance-1
分析:
-
首先将两个输入的字符串转换为整数进行加法计算:
int(string1) + int(string2),然后再将结果转换回字符串来进一步处理。这个步骤是解决大数相加问题的关键,因为字符串直接进行加法运算是不允许的(尤其是大数的情况下)。 -
我们在代码中使用了列表推导式来找出所有最大和最小数字的索引位置:
[i for i, d in enumerate(sum_result) if d == max_digit]。这样写会更简洁高效,可以直接通过循环查找字符在字符串中的位置。 -
这道题目帮助我更好地理解了如何通过字符串的遍历和索引计算来解决复杂的问题,同时也让我思考如何在有多个重复数字时高效地处理最小位差的计算。
11月2日 股票市场交易策略优化
问题描述
小R近期表现出色,公司决定以股票的形式给予奖励,并允许他在市场上进行交易以最大化收益。给定一个数组,数组中的第i个元素代表第i天的股票价格。小R需要设计一个算法来实现最大利润。
股票交易规则如下: 小R可以多次买卖股票,但在买入新的股票前必须卖出之前的股票。每次卖出股票后存在一天的冷冻期,在冷冻期内小R不能购买股票你的任务是帮助小R计算出在遵守交易规则的情况下能够获得的最大利润。
stocks:一个整数列表,表示连续几天内的股票价格.
思考
-
这道题目是典型的动态规划问题,涉及到股票交易的最大利润计算,且在交易规则上有一定的限制:在卖出股票后有一天的冷冻期,在此期间不能进行买入操作。目标是计算在遵守这些规则下的最大利润。
-
要解决这个问题,我们使用 动态规划 来记录不同状态下的最大利润,并逐步更新状态。我们定义三个状态变量来表示不同的操作:
hold[i]: 第i天持有股票的最大利润。即如果到第i天还持有股票,hold[i]是当天最大利润。cooldown[i]: 第i天在冷冻期的最大利润。即如果当天是冷冻期,表示我们在i-1天卖出了股票后进入冷冻期,那么cooldown[i]是当天最大利润。free[i]: 第i天没有股票,且不处于冷冻期的最大利润。即如果今天没有持有股票并且不是冷冻期,那么free[i]是当天最大利润。
-
我们最终关心的是第
n-1天的最大利润,可以是 free[n-1] 或 cooldown[n-1]。因为在最后一天可能没有持有股票且不在冷冻期(free[n-1]),也可能是处于冷冻期(cooldown[n-1])。
代码
def solution(stocks): n = len(stocks) if n < 2: return 0 # 初始化动态规划数组 hold = [0] * n cooldown = [0] * n free = [0] * n # 初始状态 hold[0] = -stocks[0] # 第一天买入股票 cooldown[0] = 0 free[0] = 0 for i in range(1, n): hold[i] = max(hold[i - 1], free[i - 1] - stocks[i]) cooldown[i] = hold[i - 1] + stocks[i] free[i] = max(free[i - 1], cooldown[i - 1]) # 返回最后一天的最大收益 return max(free[-1], cooldown[-1])
分析
-
这道题目通过动态规划很自然地将问题分解为多个子问题。每个状态只依赖于前一天的状态,这使得我们可以在 O(n) 时间复杂度内解决问题。
-
这道题表面上看,似乎可以通过贪心策略来选择每天是否交易,但由于存在冷冻期(今天买入前必须先卖出并冷冻一天),所以问题更适合动态规划来求解。
11月3日 视频推荐的算法
问题描述
西瓜视频正在开发一个新功能,旨在将访问量达到80百分位数以上的视频展示在首页的推荐列表中。实现一个程序,计算给定数据中的80百分位数。
例如:假设有一个包含从1到100的整数数组,80百分位数的值为80,因为按升序排列后,第80%位的数字就是80.
99 百分位数:假如有 N个数据,将数据从小到大排列,99 百分位数是第 N99%位置处的数据(遇到小数时四舍五入获取整数)一般计算逻辑是先排序,定位到N99%的位置。返回该位处的数据。同理,80百分位数就是第 N*80%位置处的数据。
思考
- 先需要将输入的数据转换为整数列表,并进行升序排序。排序后的数据有助于准确找到位置对应的值
- 假设有 N 个数据,80百分位数的位置是 N * 80%,也就是 N * 0.8。如果这个位置是小数,我们需要四舍五入到最近的整数,得到最终的位置索引。
- 最终,获取从排序后列表中计算出来的索引位置的值,返回这个值即为80百分位数。
代码
def solution(data): # 将输入的字符串转换为整数列表 nums = list(map(int, data.split(','))) # 对数据进行升序排序 nums.sort() # 计算80百分位数的位置索引,四舍五入到最近的整数 index = round(len(nums) * 0.8) - 1 # 返回该索引对应的值 return nums[index]
分析
- data.split(',') 将输入的字符串按逗号分割,得到一个包含数字字符的列表。
- map(int, data.split(',')) 将每个字符转化为整数,形成一个整数列表。
- nums.sort() 对数字列表进行升序排序。
- round()函数将该位置四舍五入为整数。由于 Python 中的 round() 函数对 .5 的处理是向偶数舍入,因此我们可以直接使用它来获得位置。
- 通过排序和定位80百分位数的位置,可以快速计算出所需的百分位数值。此算法的核心是排序和计算位置。