
获得徽章 20
#刷题交流# 第26天:阿D的最佳飞行路线探索
可以使用广度优先搜索(BFS)算法来解决这个问题。BFS适用于无权图中的最短路径问题,并且可以保证我们找到的是从起点到终点的最短路径。具体步骤如下:
1. 构建一个邻接表表示的图,用来存储哪些机场可以直接飞往。
2. 使用队列来进行广度优先搜索,同时用一个集合来记录已经访问过的机场以避免重复访问。
3. 从起点开始进行搜索,每次从队列中取出一个机场,并检查其所有邻居(包括左右相邻的机场和相同航空公司的其他机场)。对于每一个未访问过的邻居,将其加入队列并标记为已访问。
4. 每次从一个机场飞往另一个机场时,起飞次数加1。
5. 当到达终点时,返回当前的起飞次数作为答案。
可以使用广度优先搜索(BFS)算法来解决这个问题。BFS适用于无权图中的最短路径问题,并且可以保证我们找到的是从起点到终点的最短路径。具体步骤如下:
1. 构建一个邻接表表示的图,用来存储哪些机场可以直接飞往。
2. 使用队列来进行广度优先搜索,同时用一个集合来记录已经访问过的机场以避免重复访问。
3. 从起点开始进行搜索,每次从队列中取出一个机场,并检查其所有邻居(包括左右相邻的机场和相同航空公司的其他机场)。对于每一个未访问过的邻居,将其加入队列并标记为已访问。
4. 每次从一个机场飞往另一个机场时,起飞次数加1。
5. 当到达终点时,返回当前的起飞次数作为答案。
展开
评论
点赞
#刷题交流# 第25天:小C的类二进制拼图
解题思路:这个问题可以通过分析类二进制数的性质来解决。类二进制数只包含0和1两个数字,因此任何位置上的数字如果不是0就是1。对于给定的一个正整数n(以字符串形式给出),要找到最少的类二进制数之和等于n,关键在于观察n中每一位的最大值。
对于每一个位上的数字,如果它是k (1 ≤ k ≤ 9),那么就需要k个类二进制数在该位上贡献1才能满足条件。这是因为每个类二进制数在该位上只能提供0或1的贡献。所以,对于一个给定的数字n,我们只需要找出它所有位数中最大的数字,这个数字就代表了最少需要多少个类二进制数相加才能得到n。
根据这个思路,我们可以直接遍历字符串n,找出其中的最大数字,这个最大数字就是答案。
🌲一行代码解决:max_digit = max([int(digit) for digit in n])
解题思路:这个问题可以通过分析类二进制数的性质来解决。类二进制数只包含0和1两个数字,因此任何位置上的数字如果不是0就是1。对于给定的一个正整数n(以字符串形式给出),要找到最少的类二进制数之和等于n,关键在于观察n中每一位的最大值。
对于每一个位上的数字,如果它是k (1 ≤ k ≤ 9),那么就需要k个类二进制数在该位上贡献1才能满足条件。这是因为每个类二进制数在该位上只能提供0或1的贡献。所以,对于一个给定的数字n,我们只需要找出它所有位数中最大的数字,这个数字就代表了最少需要多少个类二进制数相加才能得到n。
根据这个思路,我们可以直接遍历字符串n,找出其中的最大数字,这个最大数字就是答案。
🌲一行代码解决:max_digit = max([int(digit) for digit in n])
展开
评论
点赞
#刷题交流# 第24天:五子棋获胜策略
算法设计
为了实现此问题可以采取以下步骤:
1. 遍历棋盘:需要遍历整个棋盘,检查每一个空位(值为0的地方),看是否可以在该处放置一枚新的白色棋子(值设为1)。
2. 检测五子连珠:对于每个空位,编写一个辅助函数,它会沿着四个主要方向(横向、纵向、左斜向和右斜向)进行检查。在每个方向上,我们会从当前点开始,向前和向后各检查四个位置,总共九个位置,以确定是否存在五个连续的白色棋子。
3.回溯::每次尝试放置新棋子后,如果发现可以形成五子连线,则记录下该位置;之后,必须移除这个假设的棋子(即恢复原状),以便继续测试其他位置。
4.结果输出:最终,我们会返回所有符合条件的位置列表,这些位置是通过添加一个新的白色棋子而能形成五子连线的地方。
算法设计
为了实现此问题可以采取以下步骤:
1. 遍历棋盘:需要遍历整个棋盘,检查每一个空位(值为0的地方),看是否可以在该处放置一枚新的白色棋子(值设为1)。
2. 检测五子连珠:对于每个空位,编写一个辅助函数,它会沿着四个主要方向(横向、纵向、左斜向和右斜向)进行检查。在每个方向上,我们会从当前点开始,向前和向后各检查四个位置,总共九个位置,以确定是否存在五个连续的白色棋子。
3.回溯::每次尝试放置新棋子后,如果发现可以形成五子连线,则记录下该位置;之后,必须移除这个假设的棋子(即恢复原状),以便继续测试其他位置。
4.结果输出:最终,我们会返回所有符合条件的位置列表,这些位置是通过添加一个新的白色棋子而能形成五子连线的地方。
展开
2
1
#刷题交流# 第21天:小D的`abc`变换问题
解题思路:
首先,定义一个函数 changeLetter,它的作用是根据给定的字符进行对应的变换。具体来说,就是通过判断传入的字符是‘a’、‘b’还是‘c’,然后分别返回对应的变换后的字符串,比如传入‘a’就返回‘bc’,传入‘b’返回‘ca’,传入‘c’返回‘ab’。
定义另一个函数 changeLetterList。它接收原始字符串 s 和操作次数 k 作为参数。在函数内部,通过一个循环来重复进行操作,循环次数就是给定的 k 值。每次循环时,会利用生成器表达式和 join 函数,将原字符串中的每个字符都经过 changeLetter 函数进行变换,然后把变换后的结果拼接起来,得到新的字符串,并且将新字符串赋值给原字符串变量,以便下一次循环继续基于新的状态进行变换。
核心代码:
def changeLetter(alpha):
if alpha == 'a':
alpha = 'bc'
elif alpha == 'b':
alpha = 'ca'
elif alpha == 'c':
alpha ='ab'
return alpha
def changeLetterList(s,k):
new_s = ''
for _ in range(k):
new_s = ''.join(changeLetter(ch) for ch in s)
s = new_s
return new_s
21天,21天,加油⛽️!!!
解题思路:
首先,定义一个函数 changeLetter,它的作用是根据给定的字符进行对应的变换。具体来说,就是通过判断传入的字符是‘a’、‘b’还是‘c’,然后分别返回对应的变换后的字符串,比如传入‘a’就返回‘bc’,传入‘b’返回‘ca’,传入‘c’返回‘ab’。
定义另一个函数 changeLetterList。它接收原始字符串 s 和操作次数 k 作为参数。在函数内部,通过一个循环来重复进行操作,循环次数就是给定的 k 值。每次循环时,会利用生成器表达式和 join 函数,将原字符串中的每个字符都经过 changeLetter 函数进行变换,然后把变换后的结果拼接起来,得到新的字符串,并且将新字符串赋值给原字符串变量,以便下一次循环继续基于新的状态进行变换。
核心代码:
def changeLetter(alpha):
if alpha == 'a':
alpha = 'bc'
elif alpha == 'b':
alpha = 'ca'
elif alpha == 'c':
alpha ='ab'
return alpha
def changeLetterList(s,k):
new_s = ''
for _ in range(k):
new_s = ''.join(changeLetter(ch) for ch in s)
s = new_s
return new_s
21天,21天,加油⛽️!!!
展开
评论
1
#刷题交流# 第20天:股票市场交易策略优化
为了帮助小R计算出在遵守交易规则的情况下能够获得的最大利润,我们可以使用动态规划(Dynamic Programming, DP)的方法来解决问题。我们定义三个状态:
● hold:表示持有股票时的最大收益。
● sell:表示卖出股票后的最大收益。
● rest:表示处于冷冻期或选择休息(不买卖)时的最大收益。
这三个状态之间的转移方程如下:
● hold[i] = max(hold[i - 1], rest[i - 1] - price[i]):要么保持之前的持有状态,要么从冷冻期后购买新股票。
● sell[i] = hold[i - 1] + price[i]:只能从前一天的持有状态转变而来,表示今天卖出股票。
● rest[i] = max(rest[i - 1], sell[i - 1]):要么从前一天的冷冻期或卖出状态转变而来,表示今天不进行任何操作。
初始条件为:
● hold[0] = -price[0]:第一天买入股票后的收益。
● sell[0] = 0:第一天没有可以卖出的股票。
● rest[0] = 0:第一天没有之前的操作,所以休息的收益为0。
最后的结果是最后一天的 sell 和 rest 状态中的较大值,因为如果最后一天持有股票则不是最优解(除非最后一日的股价为负,但这是题目所不允许的情况)。
核心代码:
# 初始化状态
hold, sell, rest = -stocks[0], 0, 0
for i in range(1, len(stocks)):
# 必须先保存旧的 hold 值,因为它会被新的 hold 值覆盖,而 sell 需要使用旧的 hold 值
old_hold = hold
hold = max(hold, rest - stocks[i])
rest = max(rest, sell)
sell = old_hold + stocks[i]
# 返回最后一天 sell 或 rest 状态中的较大值
return max(sell, rest)
20天了,加油⛽️ 不积跬步,无以至千里;不积小流,无以成江海。
为了帮助小R计算出在遵守交易规则的情况下能够获得的最大利润,我们可以使用动态规划(Dynamic Programming, DP)的方法来解决问题。我们定义三个状态:
● hold:表示持有股票时的最大收益。
● sell:表示卖出股票后的最大收益。
● rest:表示处于冷冻期或选择休息(不买卖)时的最大收益。
这三个状态之间的转移方程如下:
● hold[i] = max(hold[i - 1], rest[i - 1] - price[i]):要么保持之前的持有状态,要么从冷冻期后购买新股票。
● sell[i] = hold[i - 1] + price[i]:只能从前一天的持有状态转变而来,表示今天卖出股票。
● rest[i] = max(rest[i - 1], sell[i - 1]):要么从前一天的冷冻期或卖出状态转变而来,表示今天不进行任何操作。
初始条件为:
● hold[0] = -price[0]:第一天买入股票后的收益。
● sell[0] = 0:第一天没有可以卖出的股票。
● rest[0] = 0:第一天没有之前的操作,所以休息的收益为0。
最后的结果是最后一天的 sell 和 rest 状态中的较大值,因为如果最后一天持有股票则不是最优解(除非最后一日的股价为负,但这是题目所不允许的情况)。
核心代码:
# 初始化状态
hold, sell, rest = -stocks[0], 0, 0
for i in range(1, len(stocks)):
# 必须先保存旧的 hold 值,因为它会被新的 hold 值覆盖,而 sell 需要使用旧的 hold 值
old_hold = hold
hold = max(hold, rest - stocks[i])
rest = max(rest, sell)
sell = old_hold + stocks[i]
# 返回最后一天 sell 或 rest 状态中的较大值
return max(sell, rest)
20天了,加油⛽️ 不积跬步,无以至千里;不积小流,无以成江海。
展开
4
6
#刷题交流# 第19天:最少前缀操作问题
暴力枚举前缀长度:
○ 我们首先考虑 T 的所有可能前缀,从长度为 0 到 min(len(S), len(T))。对于每个可能的前缀长度 i,我们取出 S 的前 i 个字符组成 cur_s。
○ 计算将 S 变为长度为 i 的 T 的前缀所需的操作次数。操作次数初始化为将 S 截断到长度 i 所需删除末尾字符的次数,即 len(S) - i。
○ 然后,我们逐个比较 cur_s 和 T 的前 i 个字符,如果字符不相同,则需要一次修改操作,将操作次数加 1。
○ 最后,我们更新全局的最少操作次数 min_op。
核心代码:
# 枚举T的可能前缀长度
for i in range(min(m, n) + 1):
cur_s = S[:i]
op_count = len(S) - i
# 计算当前前缀下的操作次数
for j in range(len(cur_s)):
if cur_s[j]!= T[j]:
op_count += 1
# 更新最少操作次数
min_op = min(min_op, op_count)
加油⛽️加油
,19天了。
暴力枚举前缀长度:
○ 我们首先考虑 T 的所有可能前缀,从长度为 0 到 min(len(S), len(T))。对于每个可能的前缀长度 i,我们取出 S 的前 i 个字符组成 cur_s。
○ 计算将 S 变为长度为 i 的 T 的前缀所需的操作次数。操作次数初始化为将 S 截断到长度 i 所需删除末尾字符的次数,即 len(S) - i。
○ 然后,我们逐个比较 cur_s 和 T 的前 i 个字符,如果字符不相同,则需要一次修改操作,将操作次数加 1。
○ 最后,我们更新全局的最少操作次数 min_op。
核心代码:
# 枚举T的可能前缀长度
for i in range(min(m, n) + 1):
cur_s = S[:i]
op_count = len(S) - i
# 计算当前前缀下的操作次数
for j in range(len(cur_s)):
if cur_s[j]!= T[j]:
op_count += 1
# 更新最少操作次数
min_op = min(min_op, op_count)
加油⛽️加油
展开
评论
2
#刷题交流# 第18天:观光景点组合得分问题
要找到一对观光景点 (i < j) 的最高得分,我们可以使用一个更高效的方法,而不是对每个可能的组合都进行两两比较。关键在于我们可以通过一次遍历就解决问题,同时维护一个当前的最佳选择。
对于任意一对 (i, j),得分计算公式为:values[i] + values[j] + i - j,可以重写为 (values[i] + i) + (values[j] - j)。因此,当我们在遍历数组时,我们可以一边遍历一边维护最大值 values[i] + i,然后在每次迭代中计算当前的 values[j] - j 并与之前的最大值相加得到可能的最高分。
解决问题的算法步骤如下:
1. 初始化变量 max_score 用于保存最高的观光组合得分,设为负无穷大或一个非常小的数。
2. 初始化变量 max_value_plus_index 保存到目前为止遇到的最大 values[i] + i 值。
3. 开始遍历数组,从第二个元素开始(因为至少需要两个景点来形成组合)。
4. 对于每个元素 values[j],根据公式 (values[j] - j) + max_value_plus_index 计算当前得分,并更新 max_score。
5. 更新 max_value_plus_index 为 max(max_value_plus_index, values[j] + j),确保它总是包含到目前为止的最大 values[i] + i。
6. 遍历结束后,max_score 就是所求的最高得分。
这个算法的时间复杂度是 O(n),其中 n 是数组的长度,因为我们只遍历了一次数组。空间复杂度是 O(1),因为我们只用了常量级别的额外空间。
第18天了,加油!!!
要找到一对观光景点 (i < j) 的最高得分,我们可以使用一个更高效的方法,而不是对每个可能的组合都进行两两比较。关键在于我们可以通过一次遍历就解决问题,同时维护一个当前的最佳选择。
对于任意一对 (i, j),得分计算公式为:values[i] + values[j] + i - j,可以重写为 (values[i] + i) + (values[j] - j)。因此,当我们在遍历数组时,我们可以一边遍历一边维护最大值 values[i] + i,然后在每次迭代中计算当前的 values[j] - j 并与之前的最大值相加得到可能的最高分。
解决问题的算法步骤如下:
1. 初始化变量 max_score 用于保存最高的观光组合得分,设为负无穷大或一个非常小的数。
2. 初始化变量 max_value_plus_index 保存到目前为止遇到的最大 values[i] + i 值。
3. 开始遍历数组,从第二个元素开始(因为至少需要两个景点来形成组合)。
4. 对于每个元素 values[j],根据公式 (values[j] - j) + max_value_plus_index 计算当前得分,并更新 max_score。
5. 更新 max_value_plus_index 为 max(max_value_plus_index, values[j] + j),确保它总是包含到目前为止的最大 values[i] + i。
6. 遍历结束后,max_score 就是所求的最高得分。
这个算法的时间复杂度是 O(n),其中 n 是数组的长度,因为我们只遍历了一次数组。空间复杂度是 O(1),因为我们只用了常量级别的额外空间。
第18天了,加油!!!
展开
评论
点赞
#刷题交流# 第17天:石子移动问题
分析
小S的石子移动游戏可以分解为以下步骤:
1. 定义端点石子:最左端和最右端的石子称为端点石子。
2. 操作目标:将石子移动到其他未占用的位置,使得所有石子的位置变得连续。
3. 计算最大移动次数:
○ 为了达到最大移动次数,可以将端点石子移动到尽可能远的位置,使得每次移动后仍然有一个端点石子,直到石子的位置变得连续。
思路
1. 单石子处理:if len(stones) <= 1,若只有一个石子,则直接返回 0。
2. 排序:首先对石子位置的数组 stones 进行排序,这样便于计算石子的位置间隔。
3. 计算两端的间隔:考虑从左端或右端开始逐步移动端点石子,直到所有石子的位置变得连续。
4. 最大移动次数:通过计算从左端到右端的间隔,以及移出端点石子所需的步数,得到最大可能的移动次数。
17天,今日冬至!加油⛽️
分析
小S的石子移动游戏可以分解为以下步骤:
1. 定义端点石子:最左端和最右端的石子称为端点石子。
2. 操作目标:将石子移动到其他未占用的位置,使得所有石子的位置变得连续。
3. 计算最大移动次数:
○ 为了达到最大移动次数,可以将端点石子移动到尽可能远的位置,使得每次移动后仍然有一个端点石子,直到石子的位置变得连续。
思路
1. 单石子处理:if len(stones) <= 1,若只有一个石子,则直接返回 0。
2. 排序:首先对石子位置的数组 stones 进行排序,这样便于计算石子的位置间隔。
3. 计算两端的间隔:考虑从左端或右端开始逐步移动端点石子,直到所有石子的位置变得连续。
4. 最大移动次数:通过计算从左端到右端的间隔,以及移出端点石子所需的步数,得到最大可能的移动次数。
17天,今日冬至!加油⛽️
展开
评论
点赞
#刷题交流# 第16天:统计班级中的说谎者
解决这个问题,我们需要判断每个学生的分数相对于其他学生的排名位置是否满足说谎的条件。具体分析如下:
1. 统计分数排名:
○ 对于每个学生的成绩A_i,统计比A_i小或相等的学生数量和比A_i大的学生数量。
○ 如果“分数小于等于他的学生数量”大于“分数比他高的学生数量”,则该学生会说谎。
2. 排序并统计前缀频次:
○ 我们可以先对成绩数组A进行排序,这样可以方便地计算每个分数的排名位置。
○ 使用前缀统计,计算每个分数的频次及小于等于当前分数的学生数量。
3. 遍历并判断:
○ 对于每个学生,利用排序结果和前缀频次统计,判断是否满足说谎条件。
解决这个问题,我们需要判断每个学生的分数相对于其他学生的排名位置是否满足说谎的条件。具体分析如下:
1. 统计分数排名:
○ 对于每个学生的成绩A_i,统计比A_i小或相等的学生数量和比A_i大的学生数量。
○ 如果“分数小于等于他的学生数量”大于“分数比他高的学生数量”,则该学生会说谎。
2. 排序并统计前缀频次:
○ 我们可以先对成绩数组A进行排序,这样可以方便地计算每个分数的排名位置。
○ 使用前缀统计,计算每个分数的频次及小于等于当前分数的学生数量。
3. 遍历并判断:
○ 对于每个学生,利用排序结果和前缀频次统计,判断是否满足说谎条件。
展开
评论
点赞
赞了这篇文章
#刷题交流# 第15天:比赛配对问题
这个问题本质上是要模拟一个淘汰赛的过程,直到剩下唯一的一支获胜队伍。在每一轮中,根据队伍数的奇偶性进行配对,直到队伍数降到 1 为止。我们需要统计总共进行的比赛次数。
思路
1. 奇偶性判断:
○ 如果队伍数是偶数,则每两支队伍配对,进行n/2场比赛,剩下的队伍数也会减少为n/2。
○ 如果队伍数是奇数,则有一支队伍轮空,其他队伍配对,进行(n-1)/2场比赛,剩下的队伍数会变为 (n-1)/2 + 1(即(n+1)/2)。
2. 比赛次数累计:
○ 每进行一轮比赛时,都需要根据当前队伍数判断进行多少场比赛,并更新剩下的队伍数,直到剩下的队伍数为 1。
3. 结束条件:
○ 当队伍数剩下 1 时,比赛结束。
核心代码:
while n > 1:
if n % 2 == 0:
# 如果队伍数是偶数,每两支队伍配对
matches += n // 2
n //= 2
else:
# 如果队伍数是奇数,轮空一支队伍,其他队伍配对
matches += (n - 1) // 2
n = (n - 1) // 2 + 1
加油,15天,已经过半了!!
这个问题本质上是要模拟一个淘汰赛的过程,直到剩下唯一的一支获胜队伍。在每一轮中,根据队伍数的奇偶性进行配对,直到队伍数降到 1 为止。我们需要统计总共进行的比赛次数。
思路
1. 奇偶性判断:
○ 如果队伍数是偶数,则每两支队伍配对,进行n/2场比赛,剩下的队伍数也会减少为n/2。
○ 如果队伍数是奇数,则有一支队伍轮空,其他队伍配对,进行(n-1)/2场比赛,剩下的队伍数会变为 (n-1)/2 + 1(即(n+1)/2)。
2. 比赛次数累计:
○ 每进行一轮比赛时,都需要根据当前队伍数判断进行多少场比赛,并更新剩下的队伍数,直到剩下的队伍数为 1。
3. 结束条件:
○ 当队伍数剩下 1 时,比赛结束。
核心代码:
while n > 1:
if n % 2 == 0:
# 如果队伍数是偶数,每两支队伍配对
matches += n // 2
n //= 2
else:
# 如果队伍数是奇数,轮空一支队伍,其他队伍配对
matches += (n - 1) // 2
n = (n - 1) // 2 + 1
加油,15天,已经过半了!!
展开
评论
1
#刷题交流# 第14天:小B的极差之和
问题分析:
我们需要求出数组 b 的所有连续子数组的极差之和,极差定义为子数组中的最大值减去最小值。
给定数组 a,它描述了如何构造数组 b,数组 b 中有 a[i] 个 i+1。例如,如果 a = [2, 3, 1],那么数组 b 将是 [1, 1, 2, 2, 2, 3]。
目标:
1. 构造数组 b。
2. 计算所有连续子数组的极差之和。
由于构造数组 b 可能非常大(最大可能的长度为 sum(a)),直接遍历所有子数组并计算其极差是不现实的。我们需要通过一种优化的方法来处理这个问题。
解决方案
1. 构造数组 b:直接根据数组 a 构造数组 b,每个元素 i+1 出现 a[i] 次。
2. 计算极差:我们需要考虑如何快速计算数组 b 中所有子数组的极差之和。
○ 对于每个元素 x,我们需要知道它作为子数组最大值或最小值的贡献。
○ 假设元素 x 在某些子数组中是最大值或最小值,那么我们需要计算这个元素作为最大值或最小值的子数组的数量。
3. 优化计算:可以通过单调栈来计算每个元素作为最大值和最小值出现的次数,进而计算其对极差的贡献。
问题分析:
我们需要求出数组 b 的所有连续子数组的极差之和,极差定义为子数组中的最大值减去最小值。
给定数组 a,它描述了如何构造数组 b,数组 b 中有 a[i] 个 i+1。例如,如果 a = [2, 3, 1],那么数组 b 将是 [1, 1, 2, 2, 2, 3]。
目标:
1. 构造数组 b。
2. 计算所有连续子数组的极差之和。
由于构造数组 b 可能非常大(最大可能的长度为 sum(a)),直接遍历所有子数组并计算其极差是不现实的。我们需要通过一种优化的方法来处理这个问题。
解决方案
1. 构造数组 b:直接根据数组 a 构造数组 b,每个元素 i+1 出现 a[i] 次。
2. 计算极差:我们需要考虑如何快速计算数组 b 中所有子数组的极差之和。
○ 对于每个元素 x,我们需要知道它作为子数组最大值或最小值的贡献。
○ 假设元素 x 在某些子数组中是最大值或最小值,那么我们需要计算这个元素作为最大值或最小值的子数组的数量。
3. 优化计算:可以通过单调栈来计算每个元素作为最大值和最小值出现的次数,进而计算其对极差的贡献。
展开
评论
2
#刷题交流# 第13天:小U的数字插入问题
解题思路:
1. 将数字 a 转换为字符串,以便可以逐位比较。
2. 遍历字符串 a 中的每一位,尝试在每个位置插入数字 b,看哪种插入方式可以生成更大的数字。
3. 选择一个插入的位置,使得生成的数字最大。
核心代码:
# 遍历a的每一位,尝试将b插入到该位置
for i in range(len(a_str) + 1):
# 插入b的方式:a的前半部分 + b + a的后半部分
new_num = int(a_str[:i] + b_str + a_str[i:])
# 更新最大结果
max_result = max(max_result, new_num)
13天!13天!加油⛽️,努力坚持不放弃。
解题思路:
1. 将数字 a 转换为字符串,以便可以逐位比较。
2. 遍历字符串 a 中的每一位,尝试在每个位置插入数字 b,看哪种插入方式可以生成更大的数字。
3. 选择一个插入的位置,使得生成的数字最大。
核心代码:
# 遍历a的每一位,尝试将b插入到该位置
for i in range(len(a_str) + 1):
# 插入b的方式:a的前半部分 + b + a的后半部分
new_num = int(a_str[:i] + b_str + a_str[i:])
# 更新最大结果
max_result = max(max_result, new_num)
13天!13天!加油⛽️,努力坚持不放弃。
展开
评论
2
#刷题交流# 第12天:负二进制表示问题
负二进制的表示方法与普通二进制有所不同。在负二进制中,每一位的权值是 ((-2)^i),其中 (i) 是从右到左的位数索引(从0开始)。为了将一个整数 (n) 转换为负二进制表示,我们可以使用类似于普通二进制转换的方法,但需要注意处理负权值带来的影响。
转换步骤
1. 初始化:
○ 创建一个空字符串 result 用于存储结果。
○ 使用一个循环,直到 (n) 变为0。
2. 计算余数:
○ 计算 (n) 除以 -2 的余数 r。
○ 如果余数 r 为负数,则需要调整 (n) 和 r,使得 r 变为非负数。
3. 更新 (n):
○ 如果 r 为负数,将 (n) 增加1,同时将 r 加2,以确保 r 为非负数。
○ 将 r 转换为字符串并添加到 result 的前面。
4. 处理前导零:
○ 如果结果字符串为空,返回 "0"。
○ 否则,返回结果字符串。
核心代码:
while n != 0:
n, remainder = divmod(n, -2)
if remainder < 0:
n, remainder = n + 1, remainder + 2
result = str(remainder) + result
12天,加油加油,马上过半了!!!
负二进制的表示方法与普通二进制有所不同。在负二进制中,每一位的权值是 ((-2)^i),其中 (i) 是从右到左的位数索引(从0开始)。为了将一个整数 (n) 转换为负二进制表示,我们可以使用类似于普通二进制转换的方法,但需要注意处理负权值带来的影响。
转换步骤
1. 初始化:
○ 创建一个空字符串 result 用于存储结果。
○ 使用一个循环,直到 (n) 变为0。
2. 计算余数:
○ 计算 (n) 除以 -2 的余数 r。
○ 如果余数 r 为负数,则需要调整 (n) 和 r,使得 r 变为非负数。
3. 更新 (n):
○ 如果 r 为负数,将 (n) 增加1,同时将 r 加2,以确保 r 为非负数。
○ 将 r 转换为字符串并添加到 result 的前面。
4. 处理前导零:
○ 如果结果字符串为空,返回 "0"。
○ 否则,返回结果字符串。
核心代码:
while n != 0:
n, remainder = divmod(n, -2)
if remainder < 0:
n, remainder = n + 1, remainder + 2
result = str(remainder) + result
12天,加油加油,马上过半了!!!
展开
评论
2
#刷题交流# 第11天:查找按位XOR等于2的整数对问题
解题思路
1. 按位XOR的性质:
a ^ b = 2 意味着 a 和 b 在二进制表示中只有一个位不同,且该位是第1位(从右往左数)。例如,4 和 6 的二进制表示分别是 100 和 110,它们的按位XOR结果是 10,即 2。
2. 检查范围内的整数对:
○ 对于任意整数 x,如果 x + 2 也在 [L, R] 范围内,那么 (x, x + 2) 就是一对满足条件的整数对。
○ 同样,如果 x - 2 也在 [L, R] 范围内,那么 (x, x - 2) 也是一对满足条件的整数对。
3. 边界条件:
○ 需要确保 x + 2 和 x - 2 都在 [L, R] 范围内。
核心代码:
for x in range(L, R + 1):
if (x + 2 <= R and (x ^ (x + 2) == 2)) or (x - 2 >= L and (x ^ (x - 2) == 2)):
return 1
return 0
第11天了,第11天了,加油啊~~
解题思路
1. 按位XOR的性质:
a ^ b = 2 意味着 a 和 b 在二进制表示中只有一个位不同,且该位是第1位(从右往左数)。例如,4 和 6 的二进制表示分别是 100 和 110,它们的按位XOR结果是 10,即 2。
2. 检查范围内的整数对:
○ 对于任意整数 x,如果 x + 2 也在 [L, R] 范围内,那么 (x, x + 2) 就是一对满足条件的整数对。
○ 同样,如果 x - 2 也在 [L, R] 范围内,那么 (x, x - 2) 也是一对满足条件的整数对。
3. 边界条件:
○ 需要确保 x + 2 和 x - 2 都在 [L, R] 范围内。
核心代码:
for x in range(L, R + 1):
if (x + 2 <= R and (x ^ (x + 2) == 2)) or (x - 2 >= L and (x ^ (x - 2) == 2)):
return 1
return 0
第11天了,第11天了,加油啊~~
展开
1
点赞
#刷题交流# 第10天:小S的倒排索引
解决此题需要找到两个升序帖子 ID 列表的交集,并以降序返回结果。
解题方法
1. 双指针技巧:
○ 由于两个列表都是按升序排列的,我们可以使用双指针技巧来找到共同的元素。
○ 初始化两个指针,分别指向列表 a 和 b 的开头。
○ 如果列表 a 和 b 的当前指针元素相等,则说明该元素是公共元素,将其加入结果列表。
○ 如果 a 中的元素较小,则移动 a 的指针向前;否则,移动 b 的指针。
2. 结果排序:
○ 由于我们构建的交集列表是升序的,最后只需将其反转即可得到降序结果。
时间复杂度
○ 双指针方法的时间复杂度为 (O(n + m)),其中 (n) 和 (m) 分别是列表 a 和 b 的长度。
10天!!
解决此题需要找到两个升序帖子 ID 列表的交集,并以降序返回结果。
解题方法
1. 双指针技巧:
○ 由于两个列表都是按升序排列的,我们可以使用双指针技巧来找到共同的元素。
○ 初始化两个指针,分别指向列表 a 和 b 的开头。
○ 如果列表 a 和 b 的当前指针元素相等,则说明该元素是公共元素,将其加入结果列表。
○ 如果 a 中的元素较小,则移动 a 的指针向前;否则,移动 b 的指针。
2. 结果排序:
○ 由于我们构建的交集列表是升序的,最后只需将其反转即可得到降序结果。
时间复杂度
○ 双指针方法的时间复杂度为 (O(n + m)),其中 (n) 和 (m) 分别是列表 a 和 b 的长度。
10天!!
展开
评论
1
#刷题交流# 第9天:最大矩形面积问题
解题思路
1. 单调栈法:
○ 为了快速找到每一个柱子(元素)为高度的最大矩形面积,我们可以利用单调栈来计算“每个柱子的左右边界”。
○ 我们在遍历数组时,使用单调递增栈来找到每个柱子左边第一个小于它的柱子的位置和右边第一个小于它的柱子的位置。
○ 这样,对于每一个高度 ( h[i] ),我们可以计算以 ( h[i] ) 为最小高度时的最大矩形宽度,从而得到最大矩形面积。
2. 算法步骤:
○ 遍历数组,使用单调栈记录每个元素的左边和右边第一个比它小的位置。
○ 根据这些边界来计算以当前元素高度为最小高度的矩形面积。
○ 遍历所有可能的矩形面积,得到最大值。
3. 复杂度分析:
时间复杂度:O(n) ,空间复杂度:O(n)。
第9天,加油⛽️!!!
解题思路
1. 单调栈法:
○ 为了快速找到每一个柱子(元素)为高度的最大矩形面积,我们可以利用单调栈来计算“每个柱子的左右边界”。
○ 我们在遍历数组时,使用单调递增栈来找到每个柱子左边第一个小于它的柱子的位置和右边第一个小于它的柱子的位置。
○ 这样,对于每一个高度 ( h[i] ),我们可以计算以 ( h[i] ) 为最小高度时的最大矩形宽度,从而得到最大矩形面积。
2. 算法步骤:
○ 遍历数组,使用单调栈记录每个元素的左边和右边第一个比它小的位置。
○ 根据这些边界来计算以当前元素高度为最小高度的矩形面积。
○ 遍历所有可能的矩形面积,得到最大值。
3. 复杂度分析:
时间复杂度:O(n) ,空间复杂度:O(n)。
第9天,加油⛽️!!!
展开
评论
点赞