将整数按权重排序
难度:
标签:
题目描述
代码结果
运行时间: 47 ms, 内存: 16.2 MB
/*
* 思路:
* 1. 使用Stream API来处理区间 [lo, hi] 的整数。
* 2. 计算每个整数的权重,并将整数和权重映射为数组。
* 3. 按照权重和数值进行排序。
* 4. 提取排序后的第 k 个元素。
*/
import java.util.Comparator;
import java.util.stream.IntStream;
public class Solution {
public int getWeight(int x) {
int steps = 0;
while (x != 1) {
if (x % 2 == 0) {
x = x / 2;
} else {
x = 3 * x + 1;
}
steps++;
}
return steps;
}
public int getKth(int lo, int hi, int k) {
return IntStream.rangeClosed(lo, hi)
.mapToObj(i -> new int[]{i, getWeight(i)})
.sorted(Comparator.<int[]>comparingInt(a -> a[1]).thenComparingInt(a -> a[0]))
.mapToInt(a -> a[0])
.skip(k - 1)
.findFirst()
.orElse(-1);
}
}
解释
方法:
题解的核心思想是使用动态规划来计算每个整数x的权重,即变成1所需的步骤数。这里利用了缓存装饰器@cache,它存储每个已计算过的整数的权重,以避免重复计算。函数f(x)负责计算一个给定的x的权重。如果x是偶数,则x除以2;如果x是奇数,则变为3*x+1,重复此过程直到x变为1。主要的函数getKth()使用这个计算权重的函数作为排序键值,对区间[lo, hi]中的所有整数进行排序,并返回第k小的整数。
时间复杂度:
O(n log n log n)
空间复杂度:
O(n)
代码细节讲解
🦆
在题解中使用@cache装饰器的原因是什么?这种缓存方法如何帮助提高计算权重的效率?
▷🦆
函数f(x)在处理x变为1的过程中,如何确保不会进入无限循环,尤其是对于大整数的情况?
▷🦆
题解的算法是否考虑了整数溢出的问题,特别是在执行3*x + 1操作时?
▷