The power of an integer x is defined as the number of steps needed to transform x into 1 using the following steps:
if x is even then x = x / 2
if x is odd then x = 3 * x + 1
For example, the power of x = 3 is 7 because 3 needs 7 steps to become
1 (3 --> 10 --> 5 --> 16 --> 8 --> 4 --> 2 --> 1).
Given three integers lo, hi and k. The task is to sort all integers in the interval [lo, hi] by the power value in ascending order , if two or more integers have the same power value sort them by ascending order.
Return the kth integer in the range [lo, hi] sorted by the power value.
Notice that for any integer x(lo <= x <= hi) it is guaranteed that
x will transform into 1 using these steps and that the power of x is will fit in a 32-bit signed integer.
Input: lo =12, hi =15, k =2Output: 13Explanation: The power of 12is9(12-->6-->3-->10-->5-->16-->8-->4-->2-->1)The power of 13is9The power of 14is17The power of 15is17The interval sorted by the power value [12,13,14,15]. For k =2 answer is the second element which is13.Notice that 12 and 13 have the same power value and we sorted them in ascending order. Same for14 and 15.
Input: lo =7, hi =11, k =4Output: 7Explanation: The power array corresponding to the interval [7,8,9,10,11]is[16,3,19,6,14].The interval sorted by power is[8,10,11,7,9].The fourth number in the sorted array is7.
Intuition: Calculate the power (Collatz conjecture steps) for each number in the range using memoization to avoid recomputation, then sort by power value with number as tiebreaker.
Approach:
Use memoization to cache power values to avoid recalculating
For each number in range [lo, hi], calculate its power value
Create pairs of (number, power) and sort by power first, then by number
#include<vector>#include<algorithm>#include<unordered_map>usingnamespace std;
classSolution {
private: unordered_map<int, int> memo;
intgetPower(int x) {
if (x ==1) return0;
if (memo.find(x) != memo.end()) return memo[x];
int original = x;
int steps =0;
while (x !=1&& memo.find(x) == memo.end()) {
if (x %2==0) {
x = x /2;
} else {
x =3* x +1;
}
steps++;
}
// x is either 1 or found in memo
int totalSteps = steps + (x ==1?0: memo[x]);
// Backtrack and memoize
x = original;
for (int i = steps; i >0; i--) {
memo[x] = totalSteps - (steps - i);
if (x %2==0) {
x = x /2;
} else {
x =3* x +1;
}
}
return memo[original];
}
public:int getKth(int lo, int hi, int k) {
vector<pair<int, int>> nums;
for (int i = lo; i <= hi; i++) {
nums.push_back({getPower(i), i});
}
sort(nums.begin(), nums.end());
return nums[k -1].second;
}
};
classSolution {
privateval memo = mutableMapOf<Int, Int>()
privatefungetPower(x: Int): Int {
if (x ==1) return0if (memo.containsKey(x)) return memo[x]!!val original = x
var current = x
var steps = 0while (current !=1&& !memo.containsKey(current)) {
current = if (current % 2==0) {
current / 2 } else {
3 * current + 1 }
steps++ }
val totalSteps = steps + if (current ==1) 0else memo[current]!!// Backtrack and memoize
current = original
for (i in steps downTo 1) {
memo[current] = totalSteps - (steps - i)
current = if (current % 2==0) {
current / 2 } else {
3 * current + 1 }
}
return memo[original]!! }
fungetKth(lo: Int, hi: Int, k: Int): Int {
val nums = mutableListOf<Pair<Int, Int>>()
for (i in lo..hi) {
nums.add(Pair(getPower(i), i))
}
nums.sortWith { a, b ->when {
a.first != b.first -> a.first.compareTo(b.first)
else-> a.second.compareTo(b.second)
}
}
return nums[k - 1].second
}
}
defgetKth(lo: int, hi: int, k: int) -> int:
memo = {}
defget_power(x):
if x ==1:
return0if x in memo:
return memo[x]
original = x
steps =0while x !=1and x notin memo:
if x %2==0:
x = x //2else:
x =3* x +1 steps +=1 total_steps = steps + (0if x ==1else memo[x])
# Backtrack and memoize x = original
for i in range(steps, 0, -1):
memo[x] = total_steps - (steps - i)
if x %2==0:
x = x //2else:
x =3* x +1return memo[original]
nums = []
for i in range(lo, hi +1):
nums.append((get_power(i), i))
nums.sort()
return nums[k -1][1]
use std::collections::HashMap;
pubfnget_kth(lo: i32, hi: i32, k: i32) -> i32 {
letmut memo: HashMap<i32, i32>= HashMap::new();
fnget_power(x: i32, memo: &mut HashMap<i32, i32>) -> i32 {
if x ==1 {
return0;
}
iflet Some(&power) = memo.get(&x) {
return power;
}
let original = x;
letmut current = x;
letmut steps =0;
while current !=1&&!memo.contains_key(¤t) {
if current %2==0 {
current = current /2;
} else {
current =3* current +1;
}
steps +=1;
}
let total_steps = steps +if current ==1 { 0 } else { memo[¤t] };
// Backtrack and memoize
current = original;
for i in (1..=steps).rev() {
memo.insert(current, total_steps - (steps - i));
if current %2==0 {
current = current /2;
} else {
current =3* current +1;
}
}
memo[&original]
}
letmut nums = Vec::new();
for i in lo..=hi {
nums.push((get_power(i, &mut memo), i));
}
nums.sort();
nums[(k -1) asusize].1}