通过乘以 2 或附加 1 来最小化将 A 转换为 B 的操作
给定两个数字A和B ,任务是找到将A转换为B的以下操作的最小数量:
- 将当前数字乘以 2(即将数字X替换为2X )
- 将数字 1 附加到当前数字的右侧(即将数字X替换为10X + 1 )。
如果无法将A转换为B ,则打印 -1 。
例子:
Input: A = 2, B = 162
Output: 4
Explanation:
Operation 1: Change A to 2*A, so A=2*2=4
Operation 2: Change A to 2*A, so A=2*4=8.
Operation 3: Change A to 10*A+1, so A=10*8+1=81
Operation 4: Change A to 2*A, so A=2*81=162
Input: A = 4, B = 42
Output: -1
方法:这个问题可以通过递归生成所有可能的解决方案,然后从中选择最小值来解决。现在,要解决此问题,请按照以下步骤操作:
- 创建一个递归函数minOperation ,它将接受三个参数,即当前数字(cur) 、目标数字(B)和一个映射(dp)来记忆返回的结果。此函数将返回将当前数字转换为目标数字所需的最小操作数。
- 最初将A作为cur 、 B和一个空映射dp在minOperations中传递。
- 现在在每个递归调用中:
- 检查cur是否大于B ,如果大于则返回 INT_MAX ,因为无法将当前数字转换为B 。
- 检查cur是否等于B ,如果是则返回 0。
- 还要检查此函数调用的结果是否已存储在 map dp中。如果是,则从那里返回。
- 否则,为(cur* 2)和(cur*10+1)再次调用此函数,并在记忆后返回这两个中的最小结果。
- 现在,如果初始调用返回 INT_MAX,则打印 -1,因为无法将A转换为B 。否则答案是从这个函数调用返回的整数。
下面是上述方法的实现:
C++
// C++ code for the above approach
#include
using namespace std;
// Function to find
// the minimum number of operations
// needed to transform A to B
int minOperations(int cur, int B,
unordered_map& dp)
{
// If current number
// is greater than target
if (cur > B) {
return INT_MAX;
}
// if current number
// is equal to the target
if (cur == B) {
return 0;
}
// If the number of minimum
// operations required to
// change the current number
// to the target number
// is already memoised
if (dp.count(cur)) {
return dp[cur];
}
// Minimum number of operations
// required if the current element
// gets multiplied by 2
int ans1 = minOperations(cur * 2, B, dp);
// Minimum number of operations
// required if the 1 is appended to
// the right of the current element
int ans2 = minOperations(cur * 10 + 1, B, dp);
// If it is not possible
// to reach the target value
// from the current element
if (min(ans1, ans2) == INT_MAX) {
return dp[cur] = INT_MAX;
}
// Returning the minimum
// number of operations
return dp[cur] = min(ans1, ans2) + 1;
}
// Driver Code
int main()
{
int A = 2, B = 162;
unordered_map dp;
int ans = minOperations(A, B, dp);
// If A cannot be transformed to B
if (ans == INT_MAX) {
cout << -1;
}
else {
cout << ans;
}
}
Java
// Java code for the above approach
import java.util.HashMap;
class GFG {
// Function to find
// the minimum number of operations
// needed to transform A to B
static int minOperations(int cur, int B, HashMap dp) {
// If current number
// is greater than target
if (cur > B) {
return Integer.MAX_VALUE;
}
// if current number
// is equal to the target
if (cur == B) {
return 0;
}
// If the number of minimum
// operations required to
// change the current number
// to the target number
// is already memoised
if (dp.containsKey(cur)) {
return dp.get(cur);
}
// Minimum number of operations
// required if the current element
// gets multiplied by 2
int ans1 = minOperations(cur * 2, B, dp);
// Minimum number of operations
// required if the 1 is appended to
// the right of the current element
int ans2 = minOperations(cur * 10 + 1, B, dp);
// If it is not possible
// to reach the target value
// from the current element
if (Math.min(ans1, ans2) == Integer.MAX_VALUE) {
dp.put(cur, Integer.MAX_VALUE);
return dp.get(cur);
}
// Returning the minimum
// number of operations
dp.put(cur, Math.min(ans1, ans2) + 1);
return dp.get(cur);
}
// Driver Code
public static void main(String args[])
{
int A = 2, B = 162;
HashMap dp = new HashMap();
int ans = minOperations(A, B, dp);
// If A cannot be transformed to B
if (ans == Integer.MAX_VALUE) {
System.out.println(-1);
}
else {
System.out.println(ans);
}
}
}
// This code is contributed by gfgking.
Python3
# Python 3 code for the above approach
import sys
# Function to find
# the minimum number of operations
# needed to transform A to B
def minOperations(cur, B,
dp):
# If current number
# is greater than target
if (cur > B):
return sys.maxsize
# if current number
# is equal to the target
if (cur == B):
return 0
# If the number of minimum
# operations required to
# change the current number
# to the target number
# is already memoised
if (cur in dp):
return dp[cur]
# Minimum number of operations
# required if the current element
# gets multiplied by 2
ans1 = minOperations(cur * 2, B, dp)
# Minimum number of operations
# required if the 1 is appended to
# the right of the current element
ans2 = minOperations(cur * 10 + 1, B, dp)
# If it is not possible
# to reach the target value
# from the current element
if (min(ans1, ans2) == sys.maxsize):
dp[cur] = sys.maxsize
return dp[cur]
# Returning the minimum
# number of operations
dp[cur] = min(ans1, ans2) + 1
return dp[cur]
# Driver Code
if __name__ == "__main__":
A = 2
B = 162
dp = {}
ans = minOperations(A, B, dp)
# If A cannot be transformed to B
if (ans == sys.maxsize):
print(-1)
else:
print(ans)
# This code is contributed by ukasp.
C#
// C# code for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find
// the minimum number of operations
// needed to transform A to B
static int minOperations(int cur, int B,
Dictionary dp)
{
// If current number
// is greater than target
if (cur > B) {
return Int32.MaxValue;
}
// if current number
// is equal to the target
if (cur == B) {
return 0;
}
// If the number of minimum
// operations required to
// change the current number
// to the target number
// is already memoised
if (dp.ContainsKey(cur)) {
return dp[cur];
}
// Minimum number of operations
// required if the current element
// gets multiplied by 2
int ans1 = minOperations(cur * 2, B, dp);
// Minimum number of operations
// required if the 1 is appended to
// the right of the current element
int ans2 = minOperations(cur * 10 + 1, B, dp);
// If it is not possible
// to reach the target value
// from the current element
if (Math.Min(ans1, ans2) == Int32.MaxValue) {
dp[cur] = Int32.MaxValue;
return dp[cur];
}
// Returning the minimum
// number of operations
dp[cur] = Math.Min(ans1, ans2) + 1;
return dp[cur];
}
// Driver Code
public static void Main(string[] args)
{
int A = 2, B = 162;
Dictionary dp
= new Dictionary();
int ans = minOperations(A, B, dp);
// If A cannot be transformed to B
if (ans == Int32.MaxValue) {
Console.WriteLine(-1);
}
else {
Console.WriteLine(ans);
}
}
}
// This code is contributed by gaurav01.
Javascript
输出
4
时间复杂度: O(log 2 B*log 10 B)
辅助空间: O(max(log 2 B, log 10 B))