Generar todas las particiones únicas de un entero

Dado un entero positivo n, genere todas las formas únicas posibles de representar n como suma de enteros positivos. 

Ejemplos: 

  Input: n = 2
  Output: 
  2
  1 1

  Input: n = 3
  Output: 
  3
  2 1
  1 1 1
  Note: 2+1 and 1+2 are considered as duplicates.

  Input: n = 4
  Output: 
  4
  3 1
  2 2
  2 1 1
  1 1 1 1 

Solución: Imprimimos todas las particiones en orden y los números dentro de una partición también se imprimen en orden (como se muestra en los ejemplos anteriores). La idea es obtener la siguiente partición utilizando los valores de la partición actual. Almacenamos cada partición en una array p[]. Inicializamos p[] como n donde n es el número de entrada. En cada iteración. primero imprimimos p[] y luego actualizamos p[] para almacenar la siguiente partición. Entonces, el problema principal es obtener la siguiente partición de una partición dada. 

Pasos para obtener la siguiente partición de la partición actual: 
Nos dan la partición actual en p[] y su tamaño. Necesitamos actualizar p[] para almacenar la siguiente partición. Los valores en p[] deben ordenarse en orden no creciente. 

  1. Encuentre el valor no uno más a la derecha en p[] y almacene el conteo de 1 encontrado antes de un valor no uno en una variable rem_val (Indica la suma de valores en el lado derecho para actualizar). Sea k el índice de valor no uno.
  2. Disminuya el valor de p[k] en 1 y aumente rem_val en 1. Ahora puede haber dos casos: 
    • a) Si p[k] es mayor o igual que rem_val. Este es un caso simple (tenemos el orden ordenado en una nueva partición). Ponga rem_val en p[k+1] y p[0…k+1] es nuestra nueva partición.
    • b) De lo contrario (este es un caso interesante, tome p[] inicial como {3, 1, 1, 1}, p[k] disminuye de 3 a 2, rem_val aumenta de 3 a 4, divida rem_val en diferentes valores de tamaño p[k] y copie estos valores en diferentes posiciones después de p[k], por lo que la siguiente partición debería ser {2, 2, 2}).
  3. Copie p[k] a la siguiente posición, incremente k y reduzca la cuenta en p[k] mientras que p[k] es menor que rem_val. Finalmente, coloque rem_val en p[k+1] y p[0…k+1] es nuestra nueva partición. Este paso es como dividir rem_val en términos de p[k] (4 se divide en 2).

La siguiente es la implementación del algoritmo anterior: 

C++

// CPP program to generate all unique 
// partitions of an integer 
#include<iostream> 
using namespace std; 
  
// A utility function to print an array p[] of size 'n' 
void printArray(int p[], int n) 
{ 
    for (int i = 0; i < n; i++) 
    cout << p[i] << " "; 
    cout << endl; 
} 
  
void printAllUniqueParts(int n) 
{ 
    int p[n]; // An array to store a partition 
    int k = 0; // Index of last element in a partition 
    p[k] = n; // Initialize first partition as number itself 
  
    // This loop first prints current partition then generates next 
    // partition. The loop stops when the current partition has all 1s 
    while (true) 
    { 
        // print current partition 
        printArray(p, k+1); 
  
        // Generate next partition 
  
        // Find the rightmost non-one value in p[]. Also, update the 
        // rem_val so that we know how much value can be accommodated 
        int rem_val = 0; 
        while (k >= 0 && p[k] == 1) 
        { 
            rem_val += p[k]; 
            k--; 
        } 
  
        // if k < 0, all the values are 1 so there are no more partitions 
        if (k < 0) return; 
  
        // Decrease the p[k] found above and adjust the rem_val 
        p[k]--; 
        rem_val++; 
  
  
        // If rem_val is more, then the sorted order is violated. Divide 
        // rem_val in different values of size p[k] and copy these values at 
        // different positions after p[k] 
        while (rem_val > p[k]) 
        { 
            p[k+1] = p[k]; 
            rem_val = rem_val - p[k]; 
            k++; 
        } 
  
        // Copy rem_val to next position and increment position 
        p[k+1] = rem_val; 
        k++; 
    } 
} 
  
// Driver program to test above functions 
int main() 
{ 
    cout << "All Unique Partitions of 2 \n"; 
    printAllUniqueParts(2); 
  
    cout << "\nAll Unique Partitions of 3 \n"; 
    printAllUniqueParts(3); 
  
    cout << "\nAll Unique Partitions of 4 \n"; 
    printAllUniqueParts(4); 
  
    return 0; 
} 

Java

// Java program to generate all unique
// partitions of an integer
import java.io.*;
  
class GFG 
{
    // Function to print an array p[] of size n
    static void printArray(int p[], int n)
    {
        for (int i = 0; i < n; i++)
            System.out.print(p[i]+" ");
        System.out.println();
    }
      
    // Function to generate all unique partitions of an integer
    static void printAllUniqueParts(int n)
    {
        int[] p = new int[n]; // An array to store a partition
        int k = 0;  // Index of last element in a partition
        p[k] = n;  // Initialize first partition as number itself
   
        // This loop first prints current partition then generates next
        // partition. The loop stops when the current partition has all 1s
        while (true)
        {
            // print current partition
            printArray(p, k+1);
   
            // Generate next partition
   
            // Find the rightmost non-one value in p[]. Also, update the
            // rem_val so that we know how much value can be accommodated
            int rem_val = 0;
            while (k >= 0 && p[k] == 1)
            {
                rem_val += p[k];
                k--;
            }
   
            // if k < 0, all the values are 1 so there are no more partitions
            if (k < 0)  return;
   
            // Decrease the p[k] found above and adjust the rem_val
            p[k]--;
            rem_val++;
   
   
            // If rem_val is more, then the sorted order is violated.  Divide
            // rem_val in different values of size p[k] and copy these values at
            // different positions after p[k]
            while (rem_val > p[k])
            {
                p[k+1] = p[k];
                rem_val = rem_val - p[k];
                k++;
            }
   
            // Copy rem_val to next position and increment position
            p[k+1] = rem_val;
            k++;
        }
    }
      
    // Driver program
    public static void main (String[] args) 
    {
        System.out.println("All Unique Partitions of 2");
        printAllUniqueParts(2);
          
        System.out.println("All Unique Partitions of 3");
        printAllUniqueParts(3);
          
        System.out.println("All Unique Partitions of 4");
        printAllUniqueParts(4);
    }
}
  
// Contributed by Pramod Kumar

Python3

# A utility function to print an
# array p[] of size 'n'
def printArray(p, n):
    for i in range(0, n):
        print(p[i], end = " ")
    print()
  
def printAllUniqueParts(n):
    p = [0] * n     # An array to store a partition
    k = 0         # Index of last element in a partition
    p[k] = n     # Initialize first partition
                 # as number itself
  
    # This loop first prints current partition, 
    # then generates next partition.The loop 
    # stops when the current partition has all 1s
    while True:
          
            # print current partition
            printArray(p, k + 1)
  
            # Generate next partition
  
            # Find the rightmost non-one value in p[]. 
            # Also, update the rem_val so that we know
            # how much value can be accommodated
            rem_val = 0
            while k >= 0 and p[k] == 1:
                rem_val += p[k]
                k -= 1
  
            # if k < 0, all the values are 1 so 
            # there are no more partitions
            if k < 0:
                print()
                return
  
            # Decrease the p[k] found above 
            # and adjust the rem_val
            p[k] -= 1
            rem_val += 1
  
            # If rem_val is more, then the sorted 
            # order is violated. Divide rem_val in 
            # different values of size p[k] and copy 
            # these values at different positions after p[k]
            while rem_val > p[k]:
                p[k + 1] = p[k]
                rem_val = rem_val - p[k]
                k += 1
  
            # Copy rem_val to next position 
            # and increment position
            p[k + 1] = rem_val
            k += 1
  
# Driver Code
print('All Unique Partitions of 2')
printAllUniqueParts(2)
  
print('All Unique Partitions of 3')
printAllUniqueParts(3)
  
print('All Unique Partitions of 4')
printAllUniqueParts(4)
  
# This code is contributed 
# by JoshuaWorthington

C#

// C# program to generate all unique
// partitions of an integer
using System;
  
class GFG {
      
    // Function to print an array p[] 
    // of size n
    static void printArray(int []p, int n)
    {
        for (int i = 0; i < n; i++)
            Console.Write(p[i]+" ");
              
        Console.WriteLine();
    }
      
    // Function to generate all unique 
    // partitions of an integer
    static void printAllUniqueParts(int n)
    {
          
        // An array to store a partition
        int[] p = new int[n]; 
          
        // Index of last element in a 
        // partition
        int k = 0; 
          
        // Initialize first partition as 
        // number itself
        p[k] = n; 
  
        // This loop first prints current 
        // partition, then generates next
        // partition. The loop stops when 
        // the current partition has all 1s
        while (true)
        {
              
            // print current partition
            printArray(p, k+1);
  
            // Generate next partition
  
            // Find the rightmost non-one 
            // value in p[]. Also, update 
            // the rem_val so that we know
            // how much value can be 
            // accommodated
            int rem_val = 0;
              
            while (k >= 0 && p[k] == 1)
            {
                rem_val += p[k];
                k--;
            }
  
            // if k < 0, all the values are 1 so
            // there are no more partitions
            if (k < 0) 
                return;
  
            // Decrease the p[k] found above 
            // and adjust the rem_val
            p[k]--;
            rem_val++;
  
  
            // If rem_val is more, then the sorted
            // order is violated. Divide rem_val in
            // different values of size p[k] and copy
            // these values at different positions
            // after p[k]
            while (rem_val > p[k])
            {
                p[k+1] = p[k];
                rem_val = rem_val - p[k];
                k++;
            }
  
            // Copy rem_val to next position and 
            // increment position
            p[k+1] = rem_val;
            k++;
        }
    }
      
    // Driver program
    public static void Main () 
    {
        Console.WriteLine("All Unique Partitions of 2");
        printAllUniqueParts(2);
          
        Console.WriteLine("All Unique Partitions of 3");
        printAllUniqueParts(3);
          
        Console.WriteLine("All Unique Partitions of 4");
        printAllUniqueParts(4);
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to generate 
// all unique partitions 
// of an integer
  
// A utility function to 
// print an array p[] of 
// size 'n'
function printArray( $p, $n)
{
    for ($i = 0; $i < $n; $i++)
    echo $p[$i] , " ";
    echo "\n";
}
  
function printAllUniqueParts($n)
{
    // An array to store
    // a partition
    $p[$n] = array(0); 
      
    // Index of last element
    // in a partition
    $k = 0; 
      
    // Initialize first 
    // partition as number 
    // itself
    $p[$k] = $n; 
  
    // This loop first prints 
    // current partition, then 
    // generates next partition. 
    // The loop stops when the 
    // current partition has all 1s
    while (true)
    {
        // print current partition
        printArray($p, $k + 1);
  
        // Generate next partition
  
        // Find the rightmost non-one
        // value in p[]. Also, update 
        // the rem_val so that we know 
        // how much value can be accommodated
        $rem_val = 0;
        while ($k >= 0 && $p[$k] == 1)
        {
            $rem_val += $p[$k];
            $k--;
        }
  
        // if k < 0, all the values
        // are 1 so there are no 
        // more partitions
        if ($k < 0) return;
  
        // Decrease the p[k] found 
        // above and adjust the
        // rem_val
        $p[$k]--;
        $rem_val++;
  
  
        // If rem_val is more, then 
        // the sorted order is violated. 
        // Divide rem_val in different
        // values of size p[k] and copy 
        // these values at different
        // positions after p[k]
        while ($rem_val > $p[$k])
        {
            $p[$k + 1] = $p[$k];
            $rem_val = $rem_val - $p[$k];
            $k++;
        }
  
        // Copy rem_val to next
        // position and increment
        // position
        $p[$k + 1] = $rem_val;
        $k++;
    }
}
  
// Driver Code
echo "All Unique Partitions of 2 \n";
printAllUniqueParts(2);
  
echo "\nAll Unique Partitions of 3 \n";
printAllUniqueParts(3);
  
echo "\nAll Unique Partitions of 4 \n";
printAllUniqueParts(4);
  
// This code is contributed 
// by akt_mit
?>

Javascript

<script>
  
// Javascript program to generate all unique
// partitions of an integer
  
// Function to print an array p[] 
// of size n
function printArray(p, n)
{
    for(let i = 0; i < n; i++)
        document.write(p[i] + " ");
            
    document.write("</br>");
}
    
// Function to generate all unique 
// partitions of an integer
function printAllUniqueParts(n)
{
        
    // An array to store a partition
    let p = new Array(n); 
        
    // Index of last element in a 
    // partition
    let k = 0; 
        
    // Initialize first partition as 
    // number itself
    p[k] = n; 
  
    // This loop first prints current 
    // partition, then generates next
    // partition. The loop stops when 
    // the current partition has all 1s
    while (true)
    {
            
        // print current partition
        printArray(p, k + 1);
  
        // Generate next partition
  
        // Find the rightmost non-one 
        // value in p[]. Also, update 
        // the rem_val so that we know
        // how much value can be 
        // accommodated
        let rem_val = 0;
            
        while (k >= 0 && p[k] == 1)
        {
            rem_val += p[k];
            k--;
        }
  
        // If k < 0, all the values are 1 so
        // there are no more partitions
        if (k < 0) 
            return;
  
        // Decrease the p[k] found above 
        // and adjust the rem_val
        p[k]--;
        rem_val++;
  
        // If rem_val is more, then the sorted
        // order is violated. Divide rem_val in
        // different values of size p[k] and copy
        // these values at different positions
        // after p[k]
        while (rem_val > p[k])
        {
            p[k + 1] = p[k];
            rem_val = rem_val - p[k];
            k++;
        }
  
        // Copy rem_val to next position and 
        // increment position
        p[k + 1] = rem_val;
        k++;
    }
}
  
// Driver code
document.write("All Unique Partitions of 2" + "</br>");
printAllUniqueParts(2);
  
document.write("All Unique Partitions of 3" + "</br>");
printAllUniqueParts(3);
  
document.write("All Unique Partitions of 4" + "</br>");
printAllUniqueParts(4);
  
// This code is contributed by divyesh072019
  
</script>

Producción: 

All Unique Partitions of 2
2
1 1

All Unique Partitions of 3
3
2 1
1 1 1

All Unique Partitions of 4
4
3 1
2 2
2 1 1
1 1 1 1

Complejidad temporal: O(n * k)

Espacio auxiliar: O(n)
Este artículo es una contribución de Hariprasad NG . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *