Dynamic Programming学习笔记 (37) - 将整数按权重排序 (力扣# 1387)

166 阅读1分钟

本题出自力扣题库第1387题。题面大意如下:

整数x的权重定义为按照下述规则将 x 变成 1 所需要的步数:

如果 x 是偶数,那么 x = x / 2

如果 x 是奇数,那么 x = 3 * x + 1

给定三个整数 lo, hi 和 k。是将区间 [lo, hi] 之间的整数按照它们的权重升序排序,如果大于等于2个整数有相同的权重,那么按照数字自身的数值升序排序 。 返回区间 [lo, hi] 之间的整数按权重排序后的第k个数

示例:

输入:lo = 12, hi = 15, k = 2
输出:13
12 的权重为 9    
13 的权重为 9
14 的权重为 17
15 的权重为 17

题解:

本题使用的计算公式在数学中被称为考拉兹猜想,[lo, hi]之间的各个数字使用给定的规则通过一定数量的计算步骤最终都会得到1,按权重排序后的第k个数的意思也可以理解为[lo, hi]中第k个到达1的那个数字。

由此,我们可以使用一个一维数组,初始化为从lo到hi的各个数字,然后依次进行计算,得到1后,则将k递减,当k为0时,根据当前的数组下标就可以得到其对应的lo到hi之间的原始数字。

Java代码如下:

class Solution {
    public int getKth(int lo, int hi, int k) {
        int n = hi - lo + 1;
        int[] dp = new int[n];

        for (int i = 0; i < n; i++) {
            dp[i] = lo + i;
        }

        if (lo == 1) {
            k --;
        }

        while (k > 0) {
            for (int i = 0; i < n; i++) {
                if (dp[i] == 1) {
                    continue;
                }

                if (dp[i] % 2 == 0) {
                    dp[i] /= 2;
                } else {
                    dp[i] = dp[i] * 3 + 1;
                }

                if (dp[i] == 1) {
                    if (-- k == 0) {
                        return lo + i;
                    }
                }

            }
        }

        return 1;
    }
}