获得徽章 20
- #刷题交流# 第16天:统计班级中的说谎者
解决这个问题,我们需要判断每个学生的分数相对于其他学生的排名位置是否满足说谎的条件。具体分析如下:
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 - #刷题交流# 第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. 优化计算:可以通过单调栈来计算每个元素作为最大值和最小值出现的次数,进而计算其对极差的贡献。展开赞过评论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天!加油⛽️,努力坚持不放弃。展开赞过评论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 - #刷题交流# 第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点赞 - #刷题交流# 第10天:小S的倒排索引
解决此题需要找到两个升序帖子 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天,加油⛽️!!!展开评论点赞 - #刷题交流# 第7天:数字字符串格式化
题目分析:
为了完成这个任务,可以将数字字符串格式化为带千分位逗号的形式,并且去掉无用的前导零。具体步骤如下:
1. 去掉前导零:如果输入字符串是类似 0000123456 的形式,我们需要去掉所有的前导零。
2. 处理小数部分:小数部分需要保留原样,但整数部分需要加上千分位逗号。
3. 插入千分位逗号:整数部分每隔 3 个数字插入一个逗号。
4. 结合整数部分和小数部分:如果存在小数部分,将整数部分和小数部分拼接成最终结果。
解题思路:
1. 去掉字符串开头的无用零(可以用 lstrip('0') 方法)。
2. 使用字符串分割(split)将整数部分和小数部分分开(如果有小数)。
3. 对整数部分进行千分位格式化,使用 Python 内置的 format() 函数或字符串的 f-string 格式化。
4. 将整数部分和小数部分重新拼接。
加油啊!!!展开赞过12