Arranging Coins
Este problema consiste en dado un número de monedas, encontrar cuántos escalones donde el escalo i tiene i monedas se pueden armar con la cantidad de monedas dadas
Solución
impl Solution {
pub fn arrange_coins(n: i32) -> i32 {
let mut tot = 0;
let mut i = 1;
loop {
tot += i;
if tot >n{
break
}
i+=1
}
i-1
}
}
Esta solución es correcta, pero dura mucho tiempo y sobrepasa el límite de leetcode, otra solución es la siguiente:
impl Solution {
pub fn arrange_coins(n: i32) -> i32 {
let n = n as i64;
let (mut left, mut right) = (0, n);
while left <= right {
let mid = left + (right - left) / 2;
let coins = mid * (mid + 1) / 2;
if coins <= n {
left = mid + 1;
} else {
right = mid - 1;
}
}
right as i32
}
}
Esta solución se aprovecha de que el límite de el valor mayor posible que podría ser una solución es igual a n, luego podemos hacer una búsqueda binaria, evaluando si es posible armar una solución con una cantidad de números, si lo es aumentamos el valor y si no lo reducimos, resolviéndolo en log(n) tiempo. Pero existe una solución O(1), y es la siguiente
impl Solution {
pub fn arrange_coins(n: i32) -> i32 {
(((8.0 * n as f64 + 1.0).sqrt() - 1.0) / 2.0).floor() as i32
}
}
En donde sabiendo que:
$$ \frac{k(k+1)}{2} = n $$
Donde n es el número de monedas dadas
$$ k^2 + k - 2n = 0 $$
$$ k = \frac{-1 \pm \sqrt{1 + 8n}}{2} $$
Como k representa el número de filas, tomamos la raíz positiva:
$$ k = \frac{-1 + \sqrt{1 + 8n}}{2} $$
Finalmente, como necesitamos el mayor entero que no exceda la solución:
$$ \left\lfloor \frac{-1 + \sqrt{1 + 8n}}{2} \right\rfloor $$