友情支持
如果您觉得这个笔记对您有所帮助,看在D瓜哥码这么多字的辛苦上,请友情支持一下,D瓜哥感激不尽,😜
有些打赏的朋友希望可以加个好友,欢迎关注D 瓜哥的微信公众号,这样就可以通过公众号的回复直接给我发信息。
公众号的微信号是: jikerizhi 。因为众所周知的原因,有时图片加载不出来。 如果图片加载不出来可以直接通过搜索微信号来查找我的公众号。 |
1387. 将整数按权重排序
我们将整数 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 = 7, hi = 11, k = 4 输出:7 解释:区间内整数 [7, 8, 9, 10, 11] 对应的权重为 [16, 3, 19, 6, 14] 。 按权重排序后得到的结果为 [8, 10, 11, 7, 9] 。 排序后数组中第 4 个数字为 7 。
提示:
-
1 <= lo <= hi <= 1000
-
1 <= k <= hi - lo + 1
思路分析
先计算每个数字的权重,再进行比较:使用集合存储下标,通过下标找到对应的权重。计算权重时,可以递归,也可以直接循环。使用递归时,可以使用备忘录把已经计算的值存储起来,防止重复计算。
-
一刷
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* @author D瓜哥 · https://www.diguage.com
* @since 2025-05-27 19:55:53
*/
public int getKth(int lo, int hi, int k) {
int length = hi - lo + 1;
int[] step = new int[length];
for (int i = lo; i <= hi; i++) {
step[i - lo] = calc(i);
}
List<Integer> index = new ArrayList<>(length);
for (int i = 0; i < length; i++) {
index.add(i);
}
index.sort((a, b) -> {
int result = Integer.compare(step[a], step[b]);
if (result == 0) {
return Integer.compare(a, b);
} else {
return result;
}
});
return index.get(k - 1) + lo;
}
private int calc(int num) {
int result = 0;
while (num > 1) {
if ((num & 1) == 0) {
num /= 2;
} else {
num = 3 * num + 1;
}
result++;
}
return result;
}