Sword se refiere a la Oferta 17. Imprime desde 1 hasta los n dígitos más grandes (C ++) Recurrencia + DFS

Ingrese el número n e imprima en orden desde 1 hasta el número decimal de n dígitos más grande. Por ejemplo, la entrada 3, luego 1, 2, 3 se imprimirá hasta el máximo de 3 dígitos 999.

Ejemplo 1:

输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]

Descripción:
use devolver una lista de enteros en lugar de imprimir
n como un entero positivo

Solución de impresión de grandes números:

De hecho, el principal punto de prueba de esta pregunta es imprimir cuando grandes números están fuera de los límites. Deben resolverse los siguientes tres problemas:

1. Tipos de variables que representan números grandes:

No importa si es corto / int / largo ... cualquier tipo de variable, el rango de valores del número es limitado. Por lo tanto, la representación de números grandes debe ser de tipo String.
2. Genere un conjunto de cadenas de números:

Cuando se usa el tipo int, el siguiente número se puede generar con +1 en cada ronda, y este método no se puede aplicar al tipo String. Además, la eficiencia de la operación de acarreo de los números de tipo String es baja. Por ejemplo, "9999" a "10000" deben pasar del dígito de las unidades al dígito de mil, y el acarreo es de 4 veces.
La observación muestra que la lista generada es en realidad una matriz completa de n bits 0-9, por lo que se puede evitar la operación de acarreo y se puede generar una lista de cadenas de números de forma recursiva.
3. Genere de forma recursiva todas las permutaciones:

Basado en la idea del algoritmo de dividir y conquistar, primero fije el dígito alto y recurra al dígito bajo. Cuando el dígito de las unidades sea fijo, agregue una cadena de números. Por ejemplo, cuando n = 2 (rango de números 1-99), el dígito fijo de las decenas es 0-9, active la recursividad en secuencia, fije el dígito 0-9, finalice la recursividad y agregue una cadena de números.

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

class Solution {
    
    
private:
	//下面三行定义变量
	vector<int> res; 
	int nine = 0, count = 0, start, n;
	vector<char> num, loop = {
    
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
	void dfs(int x) {
    
    
        if(x == n) {
    
    //x == n才是表示完全添加索引为n-1的字符
			string s,sub;//定义字符串变量
			s.insert(s.begin()/*插入的位置*/, num.begin()/*插入对象的开始位置*/, num.end()/*插入对象的结束位置*/);
			//上一行vector<char> 转string
			sub=s.substr(start);//s的start位开始截取一段字符串
            if(!(sub=="0")) res[count++] = stoi(sub);//剔除“0”
            if(n - start == nine) start--;//设数字各位中 9 的数量为 nine ,所有位都为 9 的判断条件可用;
			//start--,表示扩增一位数,例如;“999”,start--变成n-4,为“1000”留位置
            return;//return;的作用相当于continue;用于中断此轮循环的作用,
        }
        for(char i : loop) {
    
    
            if(i == '9') nine++;//统计“9”的个数
            num[x] = i;//字符拼接到数组里面
            dfs(x + 1);//数字的下一位
        }
        nine--;//并在回溯前恢复 nine = nine - 1 。
    }
public:
    vector<int> printNumbers(int n) {
    
    
		this->n = n;
		res.resize(pow(10, n) - 1);//res数组的内存分配
		num.resize(n);//数组元素的位数内存分配
		start = n-1;//其实就是截取字符串的最后一位
		dfs(0);
		return res;
	}
};

Análisis de complejidad:

Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/qq_30457077/article/details/114754397
Recomendado
Clasificación