给定一个整数X,任务是使用以下给定的操作将1转换为X :
- 将数字乘以 2。
- 将数字乘以 3。
- 在数字上加 1。
任务是使用这三个操作打印将1转换为X所需的最小操作数,并打印执行的操作序列。
例子:
Input: X = 5
Output:
3
1 3 4 5
Explanation:
Before any operation, X = 1
1st Operation: Multiply the number 1 by 3, hence X = 3.
2nd Operation: Add 1 to the number 3, hence X = 4.
3rd Operation: Add 1 to the number 4, hence X = 5.
Therefore, minimum 3 operations are required and the sequence is 1 3 4 5.
Input: X = 20
Output:
4
1 3 9 10 20
Explanation:
Before any operation, X = 1
1st Operation: Multiply the number 1 by 3, hence X = 3.
2nd Operation: Multiply the number 3 by 3, hence X = 9.
3rd Operation: Add 1 to the number 9, hence X = 10.
4th Operation: Multiply the number 10 by 2, hence X = 20.
Therefore, minimum 4 operations are required and the sequence is 1 3 9 10 20 .
朴素的方法:最简单的方法是找到所有可能的操作序列,将1转换为X,并返回操作次数最少的那个。
时间复杂度: O(3 N )
辅助空间: O(1)
高效方法:优化上述简单方法的想法是使用动态规划找到最小操作数,然后回溯以找到所需的操作序列。以下是步骤:
- 初始化dp[]以存储每个索引 i 达到1 到 i的最小操作数。
- 现在dp[X]存储从1 生成X所需的最小操作数。我们将在自底向上方法中填充dp[]数组。对于任何值 X,我们可以通过以下方式之一减少:
- 如果 X 可以被 2 整除,则将其除以 2 并计算此操作。
- 如果 X 可以被 3 整除,则将其除以 3 并计算此操作。
- 否则从 X 中减去 1。
- 由上述步骤,形成的递推关系由下式给出:
dp[X] = min(dp[X/2] + 1, // If X is divisible by 2
dp[X/3] + 1, // If X is divisible by 3
dp[X-1] + 1)
Base Condition:
dp[1] = 0 // As no operation required when X = 1
- 创建dp[]数组后,使用数组中存储的值回溯并将序列存储在列表中。
- 打印列表中存储的最小操作和序列。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to print the Minimum number
// of operations required to convert 1
// into X by using three given operations
void printMinOperations(int N)
{
// Initialize a DP array to store
//min operations for sub-problems
int dp[N + 1];
for(int i = 0; i < N + 1; i++)
dp[i] = N;
// Base Condition:
// No operation required
// when N is 1
dp[1] = 0;
for(int i = 2; i < N + 1; i++)
{
// Multiply the number by 2
if (i % 2 == 0 && dp[i] > dp[i / 2] + 1)
dp[i] = dp[i / 2] + 1;
// Multiply the number by 3
if (i % 3 == 0 && dp[i] > dp[i / 3] + 1)
dp[i] = dp[i / 3] + 1;
// Add 1 to the number.
if (dp[i] > dp[i - 1] + 1)
dp[i] = dp[i - 1] + 1;
}
// Print the minimum operations
cout << dp[N] << endl;
// Initialize a list to store
// the sequence
vectorseq;
// Backtrack to find the sequence
while (N > 1)
{
seq.push_back(N);
// If add by 1
if(dp[N - 1] == dp[N] - 1)
N = N - 1;
// If multiply by 2
else if (N % 2 == 0 &&
dp[N / 2] == dp[N] - 1)
N = N / 2;
// If multiply by 3
else
N = N / 3;
}
seq.push_back(1);
// Print the sequence of operation
for(int i = seq.size() - 1; i >= 0; i--)
cout << seq[i] << " ";
cout << endl;
}
// Driver code
int main()
{
// Given number X
int X = 96234;
// Function call
printMinOperations(X);
}
// This code is contributed by Stream_Cipher
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to print the Minimum number
// of operations required to convert 1
// into X by using three given operations
static void printMinOperations(int N)
{
// Initialize a DP array to store
//min operations for sub-problems
int dp[] = new int[N + 1];
for(int i = 0; i < N + 1; i++)
dp[i] = N;
// Base Condition:
// No operation required
// when N is 1
dp[1] = 0;
for(int i = 2; i < N + 1; i++)
{
// Multiply the number by 2
if (i % 2 == 0 && dp[i] > dp[i / 2] + 1)
dp[i] = dp[i / 2] + 1;
// Multiply the number by 3
if (i % 3 == 0 && dp[i] > dp[i / 3] + 1)
dp[i] = dp[i / 3] + 1;
// Add 1 to the number.
if (dp[i] > dp[i - 1] + 1)
dp[i] = dp[i - 1] + 1;
}
// Print the minimum operations
System.out.println(dp[N]);
// Initialize a list to store
// the sequence
Vector seq = new Vector();
// Backtrack to find the sequence
while (N > 1)
{
seq.add(N);
// If add by 1
if(dp[N - 1] == dp[N] - 1)
N = N - 1;
// If multiply by 2
else if (N % 2 == 0 &&
dp[N / 2] == dp[N] - 1)
N = N / 2;
// If multiply by 3
else
N = N / 3;
}
seq.add(1);
// Print the sequence of operation
for(int i = seq.size() - 1; i >= 0; i--)
System.out.print(seq.get(i) + " ");
}
// Driver code
public static void main(String args[])
{
// Given number X
int X = 96234;
// Function call
printMinOperations(X);
}
}
// This code is contributed by Stream_Cipher
Python3
# Python3 program for the above approach
# Function to print the Minimum number
# of operations required to convert 1
# into X by using three given operations
def printMinOperations(N):
# Initialize a DP array to store
# min operations for sub-problems
dp = [N]*(N + 1)
# Base Condition:
# No operation required
# when N is 1
dp[1] = 0
for i in range(2, N + 1):
# Multiply the number by 2
if (i % 2 == 0 and dp[i] > dp[i//2]+1):
dp[i] = dp[i//2]+1
# Multiply the number by 3
if (i % 3 == 0 and dp[i] > dp[i//3]+1):
dp[i] = dp[i//3]+1
# Add 1 to the number.
if (dp[i] > dp[i-1]+1):
dp[i] = dp[i-1] + 1
# Print the minimum operations
print(dp[N], end ="\n")
# Initialize a list to store
# the sequence
seq = []
# Backtrack to find the sequence
while (N > 1):
seq.append(N)
# If add by 1
if dp[N-1] == dp[N] - 1:
N = N-1
# If multiply by 2
elif N % 2 == 0 and dp[N//2] == dp[N] - 1:
N = N//2
# If multiply by 3
else:
N = N//3
seq.append(1)
# Print the sequence of operation
for i in reversed(seq):
print(i, end =" ")
# Driver Code
# Given number X
X = 96234
# Function Call
printMinOperations(X)
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to print the Minimum number
// of operations required to convert 1
// into X by using three given operations
static void printMinOperations(int N)
{
// Initialize a DP array to store
//min operations for sub-problems
int []dp = new int[N + 1];
for(int i = 0; i < N + 1; i++)
dp[i] = N;
// Base Condition:
// No operation required
// when N is 1
dp[1] = 0;
for(int i = 2; i < N + 1; i++)
{
// Multiply the number by 2
if (i % 2 == 0 && dp[i] > dp[i / 2] + 1)
dp[i] = dp[i / 2] + 1;
// Multiply the number by 3
if (i % 3 == 0 && dp[i] > dp[i / 3] + 1)
dp[i] = dp[i / 3] + 1;
// Add 1 to the number.
if (dp[i] > dp[i - 1] + 1)
dp[i] = dp[i - 1] + 1;
}
// Print the minimum operations
Console.WriteLine(dp[N]);
// Initialize a list to store
// the sequence
List seq = new List();
// Backtrack to find the sequence
while (N > 1)
{
seq.Add(N);
// If add by 1
if(dp[N - 1] == dp[N] - 1)
N = N - 1;
// If multiply by 2
else if (N % 2 == 0 &&
dp[N / 2] == dp[N] - 1)
N = N / 2;
// If multiply by 3
else
N = N / 3;
}
seq.Add(1);
seq.Reverse();
// Print the sequence of operation
foreach(var i in seq)
{
Console.Write(i + " ");
}
}
// Driver code
public static void Main()
{
// Given number X
int X = 96234;
// Function call
printMinOperations(X);
}
}
// This code is contributed by Stream_Cipher
Javascript
14
1 3 9 10 11 33 99 297 891 2673 8019 16038 16039 48117 96234
时间复杂度: O(N)
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。