Los n números 0,1 ,, n-1 están dispuestos en un círculo, comenzando con el número 0 y eliminando el número enésimo de este círculo cada vez. Encuentra el último número que queda en este círculo.
Por ejemplo, los 5 dígitos 0, 1, 2, 3 y 4 forman un círculo, y el tercer dígito se elimina cada vez del dígito 0, luego los primeros 4 dígitos eliminados son 2, 0, 4, 1, y así sucesivamente. El número restante es 3.
Ejemplo 1:
Entrada: n = 5, m = 3
Salida: 3
Ejemplo 2:
Entrada: n = 10, m = 17
Salida: 2
Restricciones:
1 <= n <= 10 ^ 5
1 <= m <= 10 ^ 6
Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof Los
derechos de autor pertenecen a la red de deducción. Comuníquese con la autorización oficial para la reimpresión comercial e indique la fuente de la reimpresión no comercial.
Código para el método recursivo:
class Solution {
public:
int lastRemaining(int n, int m) {
int s=0;
for(int i=2;i<=n;i++)
s=(s+m)%i;
return s;
}
};
Ideas de explicación oficial:
Ideas
Los requisitos en el título se pueden expresar como: dada una secuencia de longitud n, cada vez que el número de elementos m retrocede y se elimina, ¿queda el número final de elementos?
Es difícil dar una respuesta rápida a esta pregunta. Pero al mismo tiempo, también debemos ver que este problema parece tener el potencial de dividirse en subproblemas más pequeños: si sabemos que para una secuencia de longitud n-1, quedan pocos elementos, entonces podemos calcular a partir de esto La respuesta a una secuencia de longitud n.
Algoritmo
Modelamos el problema anterior como una función f (n, m), y el valor de retorno de esta función es el número de secuencia del elemento dejado atrás.
Primero, la secuencia de longitud n eliminará los m% n elementos primero, y luego permanecerá una secuencia de longitud n-1. Entonces, podemos resolver f (n-1, m) de forma recursiva, podemos saber que para los elementos n-1 restantes, quedarán los últimos elementos, establecemos la respuesta a x = f (n-1, m)
Como eliminamos el elemento m% nth, la longitud de la secuencia se convierte en n-1. Cuando conocemos la respuesta x correspondiente a f (n-1, m), también podemos saber que el último elemento eliminado de la secuencia de longitud n debería ser el elemento x contado a partir de m% n. Por lo tanto, f (n, m) = (m% n + x)% n = (m + x)% n.
Calculamos recursivamente f (n, m), f (n-1, m), f (n-2, m), ... hasta el final de la recursividad f (1, m). Cuando la longitud de la secuencia es 1, se debe dejar el único elemento y su número es 0.
class Solution {
int f(int n, int m) {
if (n == 1)
return 0;
int x = f(n - 1, m);
return (m + x) % n;
}
public:
int lastRemaining(int n, int m) {
return f(n, m);
}
};
Otros métodos:
Documento: Joseph Ring .note
link: http://note.youdao.com/noteshare?id=ab67321edaaa3c68cf7ca9dd67fb9d02&sub=445688B547AC4F569E462F485698AD8D