生成整数的所有唯一分区

给定一个正整数n,生成所有可能的唯一方法,将n表示为正整数之和。

null

例如:

  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 

解决方案: 我们按排序顺序打印所有分区,分区内的数字也按排序顺序打印(如上述示例所示)。其思想是使用当前分区中的值来获取下一个分区。我们将每个分区存储在数组p[]中。我们将p[]初始化为n,其中n是输入数。在每次迭代中。我们首先打印p[],然后更新p[]以存储下一个分区。所以主要的问题是从给定的分区中获取下一个分区。

从当前分区获取下一个分区的步骤: 我们得到了p[]中的当前分区及其大小。我们需要更新p[]来存储下一个分区。p[]中的值必须按非递增顺序排序。

  1. 在p[]中找到最右边的非一个值,并将非一个值之前遇到的1的计数存储在变量rem_val中(它表示要更新的右侧值的总和)。让非一个值的索引为k。
  2. 将p[k]的值减少1,将rem_val增加1。现在可能有两种情况:
    • a) 如果 p[k]大于或等于rem_val。这是一个简单的例子(我们在新分区中有排序顺序)。把rem_val放在p[k+1],p[0…k+1]是我们的新分区。
    • b) 否则 (这是一个有趣的例子,将初始p[]取为{3,1,1,1},p[k]从3减少到2,rem_val从3增加到4,将rem_val除以大小为p[k]的不同值,并在p[k]之后的不同位置复制这些值,因此下一个分区应该是{2,2,2})。
  3. 将p[k]复制到下一个位置,当p[k]小于rem_val时,增加k并减少p[k]的计数。最后,将rem_val放在p[k+1],p[0…k+1]是我们的新分区。这一步就像用p[k]来划分rem_val(4除以2)。

以下是上述算法的实现:

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 " ;
printAllUniqueParts(2);
cout << "All Unique Partitions of 3 " ;
printAllUniqueParts(3);
cout << "All Unique Partitions of 4 " ;
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 "" ;
}
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 " ;
printAllUniqueParts(2);
echo "All Unique Partitions of 3 " ;
printAllUniqueParts(3);
echo "All Unique Partitions of 4 " ;
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>


输出:

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

时间复杂性: O(n*k)

辅助空间: O(n) 本文由 哈利帕朗 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享