📌  相关文章
📜  通过乘以 2 或附加 1 来最小化将 A 转换为 B 的操作

📅  最后修改于: 2022-05-13 01:56:10.365000             🧑  作者: Mango

通过乘以 2 或附加 1 来最小化将 A 转换为 B 的操作

给定两个数字AB ,任务是找到将A转换为B的以下操作的最小数量:

  1. 将当前数字乘以 2(即将数字X替换为2X
  2. 将数字 1 附加到当前数字的右侧(即将数字X替换为10X + 1 )。

如果无法将A转换为B ,则打印 -1 。

例子:

方法:这个问题可以通过递归生成所有可能的解决方案,然后从中选择最小值来解决。现在,要解决此问题,请按照以下步骤操作:

  1. 创建一个递归函数minOperation ,它将接受三个参数,即当前数字(cur) 、目标数字(B)和一个映射(dp)来记忆返回的结果。此函数将返回将当前数字转换为目标数字所需的最小操作数。
  2. 最初将A作为curB和一个空映射dpminOperations中传递。
  3. 现在在每个递归调用中:
    1. 检查cur是否大于B ,如果大于则返回 INT_MAX ,因为无法将当前数字转换为B
    2. 检查cur是否等于B ,如果是则返回 0。
    3. 还要检查此函数调用的结果是否已存储在 map dp中。如果是,则从那里返回。
    4. 否则,为(cur* 2)(cur*10+1)再次调用此函数,并在记忆后返回这两个中的最小结果。
  4. 现在,如果初始调用返回 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))