获得徽章 0
- #刷题交流#
问题描述:
小C对“好数”非常感兴趣,她定义一个不含前导零的正整数为“好数”,如果它的所有数位最多包含两种不同的数字。例如,数字 23,2323,9,111,和 101 都是好数。现在小C想知道,从1到n之间有多少个好数。
例如:当n=110时,所有的1位数、2位数,以及一些3位数(如 100, 101)都是好数,一共有102个。
测试样例:
样例1:
输入:n = 110
输出:102
样例2:
输入:n = 1000
输出:352
样例3:
输入:n = 1
输出:1
问题分析:
需要计算从1到n之间有多少个“好数”。一个“好数”的定义是:它的所有数位最多包含两种不同的数字。
数据结构选择
集合(Set):用于存储和快速检查数字中的不同数位。
算法步骤:
初始化计数器:用于统计好数的数量。
遍历从1到n的所有数字:
将当前数字转换为字符串。
使用集合记录字符串中的不同数位。
如果集合的大小(即不同数位的数量)小于等于2,则该数字是好数,计数器加1。
返回计数器的值。展开评论点赞 - #刷题交流#
问题描述:
在平面直角坐标系内,有一个点 P(x, y)。我们需要构造两个圆,这两个圆必须同时满足以下两个条件:
圆与 x 轴和 y 轴都相切。
圆经过点 P。
显然,这样的圆有两个合法解。请你输出这两个解的圆的半径,要求按照从小到大的顺序输出,结果保留两位小数。
测试样例:
样例1:
输入:x = 1, y = 2
输出:['1.00', '5.00']
样例2:
输入:x = 3, y = 4
输出:['2.10', '11.90']
样例3:
输入:x = 5, y = 6
输出:['3.25', '18.75']
问题分析:
需要构造两个圆,这两个圆必须同时满足以下两个条件:
圆与 x 轴和 y 轴都相切。
圆经过点 P(x, y)。
数据结构的选择逻辑:
由于只需要计算圆的半径,因此不需要复杂的数据结构。只需要使用基本的数学公式和变量来存储计算结果。
算法步骤:
理解圆与坐标轴相切的条件:
圆与 x 轴相切意味着圆的半径等于圆心到 x 轴的距离。
圆与 y 轴相切意味着圆的半径等于圆心到 y 轴的距离。
因此,圆心必须在 (r, r) 或 (-r, r) 或 (r, -r) 或 (-r, -r) 的位置。
圆经过点 P(x, y):
圆心到点 P 的距离等于圆的半径。
设圆心为 (r, r),则有 sqrt((x - r)^2 + (y - r)^2) = r。
使用求根公式 r = (-b ± sqrt(b^2 - 4ac)) / (2a) 来求解这个二次方程。
其中,a = 1,b = -2(x + y),c = x^2 + y^2。展开评论点赞 - #刷题交流#
问题描述:
小B拥有一个数组 a,她使用这个数组构造了一个新数组 b。其中,a[i] 表示在新数组 b 中有 a[i] 个 i+1。例如,若 a = [2, 3, 1],那么新数组 b = [1, 1, 2, 2, 2, 3],因为 a[0] = 2 代表数组 b 中有 2 个 1,a[1] = 3 代表数组 b 中有 3 个 2,a[2] = 1 代表数组 b 中有 1 个 3。
现在,你需要帮助小B求出 b 数组中所有连续子数组的极差之和。由于答案可能非常大,请对 (10)^9+7 取模。数组的极差定义为子数组的最大值减去最小值。
测试样例:
样例1:
输入:n = 2,a = [2, 1]
输出:2
样例2:
输入:n = 3,a = [1, 2, 1]
输出:6
样例3:
输入:n = 4,a = [2, 3, 1, 1]
输出:26
问题分析:
需要从一个数组 a 构造一个新的数组 b,然后计算 b 中所有连续子数组的极差之和。极差定义为子数组的最大值减去最小值。
数据结构的选择逻辑:
数组 b 的构造:
数组 b 是通过将 a 中的每个元素 a[i] 对应的 i+1 重复 a[i] 次来构造的。
例如,如果 a = [2, 3, 1],那么 b = [1, 1, 2, 2, 2, 3]。
极差之和的计算:
我们需要计算 b 中所有可能的连续子数组的极差之和。
极差是子数组的最大值减去最小值。
算法步骤:
构造数组 b:
遍历数组 a,对于每个 a[i],将其对应的 i+1 重复 a[i] 次,添加到数组 b 中。
计算极差之和:
使用两层循环遍历所有可能的子数组 b[i:j+1]。
在内部循环中,动态更新当前子数组的最大值和最小值。
计算当前子数组的极差,并累加到 total_sum 中,同时取模 (10)^9+7。展开评论点赞 - #刷题交流#
问题描述:
小A拿到了一个长度为n的数组,并且定义了一个连续子数组的“权值”为该子数组内不同元素的个数。现在,她想知道,权值分别为1,2,3,…,n的子数组数量有多少个。
需要根据给定的数组,输出一个包含n个整数的数组,第i个数表示权值为i的子数组数量。
测试样例:
样例1:
输入:n = 4, a = [1, 2, 2, 3]
输出:[5, 4, 1, 0]
样例2:
输入:n = 3, a = [1, 1, 1]
输出:[6, 0, 0]
样例3:
输入:n = 5, a = [1, 2, 3, 2, 1]
输出:[5, 5, 5, 0, 0]
问题分析:
需要计算一个数组中所有可能的连续子数组的权值,并统计每个权值的子数组数量。权值定义为子数组内不同元素的个数。
数据结构选择:
计数数组:需要一个长度为 n+1 的数组 c,其中 c[i] 表示权值为 i 的子数组数量。
集合:在遍历子数组时,使用集合来记录当前子数组的不同元素个数。
算法步骤:
初始化计数数组:创建一个长度为 n+1 的数组 c,并将所有元素初始化为 0。
遍历所有可能的子数组:使用双重循环来遍历所有可能的子数组。外层循环控制子数组的起始位置,内层循环控制子数组的结束位置。使用外层循环 for i in range(n) 控制子数组的起始位置。使用内层循环 for j in range(i, n) 控制子数组的结束位置。
记录不同元素:在内层循环中,使用集合 unique_elements 记录当前子数组的不同元素。
每次内层循环中,将当前元素 a[j] 添加到集合 unique_elements 中。
计算权值并更新计数数组:在每次内层循环结束时,计算当前子数组的权值(即集合的大小),并更新计数数组 c。在每次内层循环结束时,计算当前子数组的权值 weight = len(unique_elements)。如果权值 weight 小于等于 n,则更新计数数组 c[weight] += 1。
返回结果:返回计数数组 c 中从 1 到 n 的元素,因为权值为 0 的子数组数量没有意义,即返回 c[1:]。展开评论点赞 - #刷题交流#
问题描述:
小U拿到了一个通过特殊方式压缩的字符串,其中每个字母后面可能跟着一个数字,这个数字表示该字母在解压后的字符串中需要重复的次数。如果一个字母后面没有跟随数字,那么该字母在解压后的字符串中只出现一次。请帮助小U解压这个字符串并输出最终的解压结果。
测试样例:
样例1:
输入:s = "a2b3c4"
输出:'aabbbcccc'
样例2:
输入:s = "d5ef2"
输出:'dddddeff'
样例3:
输入:s = "x3y1z"
输出:'xxxyz'
问题分析:
需要解压一个压缩字符串,其中每个字母后面可能跟着一个数字,这个数字表示该字母在解压后的字符串中需要重复的次数。如果一个字母后面没有跟随数字,那么该字母在解压后的字符串中只出现一次。
数据结构选择:
列表:用于存储解压后的字符,最后将列表连接成字符串。
算法步骤:
初始化:创建一个空列表 result 用于存储解压后的字符。初始化索引 i 为 0。
遍历字符串:使用 while 循环遍历字符串 s。使用 while 循环,条件是 i < len(s)。
提取字符:每次循环提取一个字符 char。每次循环提取当前字符 char = s[i]。将索引 i 增加 1。
检查数字:检查下一个字符是否是数字。如果是,提取数字并转换为整数 num。检查下一个字符是否是数字,即 i < len(s) and s[i].isdigit()。如果是数字,提取数字并转换为整数 num。
重复字符:将字符 char 重复 num 次并添加到 result 列表中。
处理单个字符:如果没有数字,直接将字符添加到 result 列表中。
返回结果:将 result 列表连接成字符串并返回。展开评论点赞 - #刷题交流#
问题描述:
小C、小U 和小R 三个好朋友喜欢做一些数字谜题。这次他们遇到一个问题,给定一个长度为n的数组a,他们想要找出符合特定条件的三元组 (i, j, k)。具体来说,三元组要满足 0 <= i < j < k < n,并且 max(a[i], a[j], a[k]) - min(a[i], a[j], a[k]) = 1,也就是说,最大值与最小值之差必须为1。
他们决定请你帮忙编写一个程序,计算符合这个条件的三元组数量。
测试样例:
样例1:
输入:a = [2, 2, 3, 1]
输出:2
样例2:
输入:a = [1, 3, 2, 2, 1]
输出:5
样例3:
输入:a = [1, 3, 2, 2, 1, 2]
输出:12
问题分析:
需要找到所有满足以下条件的三元组 (i, j, k):
0 <= i < j < k < n
max(a[i], a[j], a[k]) - min(a[i], a[j], a[k]) = 1
数据结构选择:
由于需要频繁地查找和比较元素,排序后的数组可以帮助我们更高效地找到满足条件的三元组。
算法步骤:
排序:首先对数组进行排序。排序后,数组中的元素会按照从小到大的顺序排列,这样可以简化后续的比较操作。
遍历:使用三重循环遍历数组,检查每个三元组是否满足条件。由于数组已经排序,我们可以确保 i < j < k 的条件自动满足。
条件检查:对于每个三元组 (a[i], a[j], a[k]),检查 max(a[i], a[j], a[k]) - min(a[i], a[j], a[k]) == 1。由于数组已经排序,max(a[i], a[j], a[k]) 和 min(a[i], a[j], a[k]) 可以直接通过 a[k] 和 a[i] 获得。在循环中,检查 a[k] - a[i] == 1,如果满足条件,则计数器 count 加一。展开评论点赞 - #刷题交流#
问题描述
小U拿到了一组排列,她想知道有多少个子区间满足区间内部的数构成一个排列。一个区间的排列是指:该区间的数包含从 1 到 k 的每个数,并且每个数恰好出现一次,这个区间的长度为 k。
例如,对于数组 [2, 1, 5, 3, 4],其中区间 [2, 2],[1,2] 和 [1, 5] 都是排列。
测试样例:
样例1:
输入:n = 5 ,a = [2, 1, 5, 3, 4]
输出:3
样例2:
输入:n = 5 ,a = [1, 2, 3, 4, 5]
输出:5
样例3:
输入:n = 4 ,a = [4, 3, 2, 1]
输出:4
问题分析:
需要找到数组中所有满足条件的子区间,这些子区间内的数构成一个排列。一个排列是指区间内的数包含从1到k的每个数,并且每个数恰好出现一次。
数据结构选择:
哈希表:用于记录当前窗口内的数字及其出现次数。哈希表可以快速插入、删除和查找元素,非常适合用于滑动窗口的场景。
双指针:用于实现滑动窗口,遍历所有可能的子区间。
算法步骤:
初始化计数器:用于记录满足条件的子区间数量。初始化计数器count为0。
遍历所有可能的子区间长度:从1到n。
滑动窗口:
使用双指针left和right来表示当前窗口的左右边界。
将右指针right向右移动,将当前元素加入窗口,并更新哈希表。
当窗口大小达到k时,检查窗口内的数字是否构成排列。
如果构成排列,则计数器加1。
移动左指针left,缩小窗口,并更新哈希表。
检查排列:
使用辅助函数使用辅助函数is_permutation检查当前窗口内的数字是否包含从1到k的所有数字,并且每个数字恰好出现一次。
详细步骤:
滑动窗口:
初始化哈希表window来记录当前窗口内的数字及其出现次数。
初始化左右指针left和right为0。
使用while循环,右指针right从0遍历到n-1。
将当前元素a[right]加入窗口,并更新哈希表。
当窗口大小达到k时,检查窗口内的数字是否构成排列。
如果构成排列,则计数器count加1。
移动左指针left,缩小窗口,并更新哈希表。展开评论点赞 - #刷题交流#
问题描述: 小F在“双十一”期间购买了N件商品。每件商品有一个价格p[i],小F可以获得的优惠取决于该商品之前的一件商品。如果某一件商品的价格p[i]大于等于前面的某个商品p[j],则小F可以享受该商品p[j]的价格作为优惠,前提是p[j]是离p[i]最近的且满足条件的商品。 例如,给定价格数组p = [9, 4, 5, 2, 4],其中p[3] = 2之前没有商品的价格小于等于p[3],因此没有优惠;而p[2] = 5可以享受最近的商品p[1] = 4的价格作为优惠。因此,任务是计算小F能获得的总优惠。 测试样例: 样例1: 输入:N = 5 ,p = [9, 4, 5, 2, 4] 输出:6 样例2: 输入:N = 4 ,p = [1, 2, 3, 5] 输出:6 样例3: 输入:N = 4 ,p = [4, 3, 2, 1] 输出:0
问题分析: 小F在购买商品时,可以享受优惠的条件是:当前商品的价格大于等于前面某个商品的价格,并且这个商品是离当前商品最近的。我们需要计算小F能获得的总优惠。 数据结构选择: 可以使用一个数组来存储商品的价格,并使用一个变量来累加总优惠。 算法步骤: 初始化总优惠:创建一个变量 total_discount 并初始化为0。 遍历商品列表:从第二个商品开始,逐个检查每个商品。 查找最近的优惠商品:对于每个商品,从当前商品的前一个商品开始,向前查找,直到找到一个价格小于等于当前商品价格的商品。 累加优惠:如果找到符合条件的商品,则将该商品的价格累加到总优惠中。 返回总优惠:遍历结束后,返回 total_discount。展开评论点赞 - #刷题交流#
问题描述:
小C 需要对一个字符串进行特殊排序,这个字符串只包含三种字符类型:字母(大小写)、数字和问号。要求你按照以下规则进行排序:
问号的原始位置必须保持不变。
数字的原始位置必须保持不变,但数字要按照从大到小排序。
字母的原始位置必须保持不变,但字母要按照字典序从小到大排序。
需要编写一个程序,帮助小C实现这个字符串的排序功能。
测试样例:
样例1:
输入:inp = "12A?zc"
输出:'21A?cz'
样例2:
输入:inp = "1Ad?z?t24"
输出:'4Ad?t?z21'
样例3:
输入:inp = "???123??zxy?"
输出:'???321??xyz?'
问题分析:
需要对一个字符串进行特殊排序,这个字符串只包含三种字符类型:字母(大小写)、数字和问号。排序规则如下:
问号的原始位置必须保持不变。
数字的原始位置必须保持不变,但数字要按照从大到小排序。
字母的原始位置必须保持不变,但字母要按照字典序从小到大排序。
数据结构选择:
问号位置的记录:可以使用一个列表来记录问号在字符串中的位置。
数字和字母的排序:可以分别使用两个列表来存储数字和字母,并对它们进行排序。
算法步骤:
记录问号的位置:遍历字符串,记录问号的位置。
使用enumerate遍历字符串,记录问号的位置。
将问号的位置存储在一个列表中。
提取并排序数字:提取所有的数字,按从大到小排序。
使用列表推导式提取字符串中的所有数字。
对提取的数字列表进行从大到小排序。
提取并排序字母:提取所有的字母,按字典序从小到大排序。
使用列表推导式提取字符串中的所有字母。
对提取的字母列表进行字典序从小到大排序。
构建结果字符串:根据问号位置、排序后的数字和字母,构建最终的结果字符串。
初始化一个空的结果列表。
遍历原始字符串,根据字符类型(问号、数字、字母)从相应的列表中取出字符,构建最终的结果字符串。展开评论点赞 - #刷题交流#
问题描述:
小U最近沉迷于一款养成类游戏,游戏中的角色拥有三项属性:体力、智力和武力,初始值均为0。随着每天的游戏进展,这些属性会逐步增加。增加情况由一个二维数组 growup 表示,每个元素是一个长度为3的一维数组,分别表示每天的体力、智力和武力增加值。例如,[[1, 1, 2], [2, 2, 1], [2, 1, 2]] 表示第一天体力增加1,智力增加1,武力增加2,第二天分别增加2,2,1,第三天分别增加2,1,2。
在游戏中,玩家可以通过学习新技能来增强角色,但前提是角色的三项属性必须达到技能学习的要求。每个技能的学习要求也用一个二维数组 skill 表示,数组中的每个元素是一个长度为3的一维数组,分别表示学习某个技能所需的最低体力、智力和武力值。
任务是根据 growup 和 skill 数组,计算出玩家在多少天内可以学习每个技能。如果无法满足某个技能的学习要求,则返回 -1。
问题分析:
需要计算玩家在多少天内可以学习每个技能。每个技能的学习要求由 skill 数组表示,而每天的属性增加由 growup 数组表示。我们需要遍历每个技能,并计算出满足该技能要求所需的最少天数。如果无法满足某个技能的要求,则返回 -1。
数据结构选择:
growup 数组:表示每天的属性增加情况。
skill 数组:表示每个技能的学习要求。
算法步骤:
初始化结果列表:创建一个结果列表 result,用于存储每个技能的学习天数。
遍历每个技能:对于每个技能,执行以下步骤:
初始化当前属性:将当前的体力、智力和武力初始化为0。
初始化天数计数器:将天数计数器 days 初始化为0。
遍历每天的属性增加情况:对于每一天的属性增加情况,累加当前的体力、智力和武力。
检查属性是否满足技能要求:在每次累加属性后,检查当前的属性是否满足技能的要求。
如果满足,记录当前的天数到 result 中,并跳出循环。
如果不满足,继续累加属性。
处理无法满足技能要求的情况:如果遍历完所有天数后仍不满足技能要求,则在 result 中记录 -1。
返回结果列表:返回 result 列表,其中包含了每个技能的学习天数。展开评论点赞