题目描述
我们将整数 x 的 权重 定义为按照下述规则将 x 变成 1 所需要的步数:
如果 x 是偶数,那么 x = x / 2
如果 x 是奇数,那么 x = 3 * x + 1
比方说,x=3 的权重为 7 。因为 3 需要 7 步变成 1 (3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1)。
给你三个整数 lo, hi 和 k 。你的任务是将区间 [lo, hi] 之间的整数按照它们的权重 升序排序 ,如果大于等于 2 个整数有 相同 的权重,那么按照数字自身的数值 升序排序 。
请你返回区间 [lo, hi] 之间的整数按权重排序后的第 k 个数。
注意,题目保证对于任意整数 x (lo <= x <= hi) ,它变成 1 所需要的步数是一个 32 位有符号整数。
示例
示例 1:
输入:lo = 12, hi = 15, k = 2
输出:13
解释:12 的权重为 9(12 --> 6 --> 3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1)
13 的权重为 9
14 的权重为 17
15 的权重为 17
区间内的数按权重排序以后的结果为 [12,13,14,15] 。对于 k = 2 ,答案是第二个整数也就是 13 。
注意,12 和 13 有相同的权重,所以我们按照它们本身升序排序。14 和 15 同理。
示例 2:
输入:lo = 1, hi = 1, k = 1
输出:1
示例 3:
输入:lo = 7, hi = 11, k = 4
输出:7
解释:区间内整数 [7, 8, 9, 10, 11] 对应的权重为 [16, 3, 19, 6, 14] 。
按权重排序后得到的结果为 [8, 10, 11, 7, 9] 。
排序后数组中第 4 个数字为 7 。
示例 4:
输入:lo = 10, hi = 20, k = 5
输出:13
示例 5:
输入:lo = 1, hi = 1000, k = 777
输出:570
提示:
1 <= lo <= hi <= 1000
1 <= k <= hi - lo + 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-integers-by-the-power-value
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解
我的思路是这样的:
1、我们先获得区间数字对应的权重列表res
2、我们对权重列表res进行排序找到第k个,但不能破坏这个权重列表,否则会丢失对应关系,copy一下tmp进行排序
3、如果权重是唯一的,我们只需要遍历一下res,找到第在tmp列表中排序对应的第k-1个权重(目标权重)对应的索引即可,使用enumerate即可,但权重不是惟一的,所以我们需要引入列表v得到res中目标权重,并引入变量n计算相对距离,示例如下
我们计算(1, 1000, 777),通过上述的计算我们会得到目标权重x = 105,我们对目标权重去res找到它对应的索引,可以得到这样的一个列表[94, 95, 568, 570, 572, 573],它们的权重都是105,我们如何才能知道我们需要返回的是哪个呢?这个列表在tmp这个排完需的数组中是这样的[105, 105, 105, 105, 105, 105],我们不知道哪个权重才是第k-1,我们去计算相对位置,用n得到目标权重到第一个不是105权重的距离,我们可以得到n =3,这也就是说我们需要返回的索引是v[3],即570
代码如下:
def getKth(lo: int, hi: int, k: int) -> int:
# 构造一个列表,存储对应的权重 0 =>lo, hi - lo => hi
res = [0] * (hi - lo + 1)
def w(n: int) -> int:
i = 0
while n != 1:
if n % 2 == 0:
n /= 2
else:
n = 3 * n + 1
i += 1
return i
for i in range(lo, hi+1):
res[i-lo] = w(i)
# 将得到的权重copy一份
tmp = [0] * (hi - lo + 1)
for i in range (hi - lo + 1):
tmp[i] = res[i]
tmp.sort()
# 排在第 k-1 的数就是我们希望return的结果对应的权重
x = tmp[k-1]
m = k - 1
n = -1
while x == tmp[m] and m >= 0:
m -= 1
n += 1
# 目标权重对应的索引可能不止一个,我们创建一个列表来存储所有的索引
v = []
for i,j in enumerate(res):
if x == j:
v.append(i+lo)
# 列表v中就是我们目标权重对应的索引结果,我们需要return的结果就在其中
# v [94, 95, 568, 570, 572, 573]
# 我们需要引入变量n,来计算 k-1 所对应的权重x 与权重x第一次出现的相对距离
return(v[n])
getKth(1, 1000, 777) # 570
给定整数区间的起始和结束值以及一个整数k,需要找到该区间内按权重升序排列的第k个数。权重定义为将数变为1所需的步骤数,偶数时除以2,奇数时乘3加1。当权重相同时,按数字本身升序排序。本题通过计算每个数的权重并排序找到目标权重的索引来解决问题。
1102

被折叠的 条评论
为什么被折叠?



