将数字 x 转换为 y 所需的最小操作次数
给定一个初始数字 x 和两个操作,如下所示:
- 将数字乘以 2。
- 从数字中减去 1。
任务是找出仅使用以上两个操作将数字 x 转换为 y 所需的最小操作数。我们可以多次应用这些操作。
约束:
1 <= x, y <= 1000
例子:
Input : x = 4, y = 7
Output : 2
We can transform x into y using following
two operations.
1. 4*2 = 8
2. 8-1 = 7
Input : x = 2, y = 5
Output : 4
We can transform x into y using following
four operations.
1. 2*2 = 4
2. 4-1 = 3
3. 3*2 = 6
4. 6-1 = 5
Answer = 4
Note that other sequences of two operations
would take more operations.
我们的想法是为此使用 BFS。我们运行 BFS 并通过乘以 2 并减去 1 来创建节点,因此我们可以从起始数字获得所有可能的数字。
要点:
1)当我们从一个数字中减去 1 并且如果它变为 < 0 即负数,则没有理由从中创建下一个节点(根据输入约束,数字 x 和 y 是正数)。
2)另外,如果我们已经创建了一个号码,那么没有理由再次创建它。即我们维护一个访问过的数组。
C++
// C++ program to find minimum number of steps needed
// to convert a number x into y with two operations
// allowed : (1) multiplication with 2 (2) subtraction
// with 1.
#include
using namespace std;
// A node of BFS traversal
struct node {
int val;
int level;
};
// Returns minimum number of operations
// needed to convert x into y using BFS
int minOperations(int x, int y)
{
// To keep track of visited numbers
// in BFS.
set visit;
// Create a queue and enqueue x into it.
queue q;
node n = { x, 0 };
q.push(n);
// Do BFS starting from x
while (!q.empty()) {
// Remove an item from queue
node t = q.front();
q.pop();
// If the removed item is target
// number y, return its level
if (t.val == y)
return t.level;
// Mark dequeued number as visited
visit.insert(t.val);
// If we can reach y in one more step
if (t.val * 2 == y || t.val - 1 == y)
return t.level + 1;
// Insert children of t if not visited
// already
if (visit.find(t.val * 2) == visit.end()) {
n.val = t.val * 2;
n.level = t.level + 1;
q.push(n);
}
if (t.val - 1 >= 0
&& visit.find(t.val - 1) == visit.end()) {
n.val = t.val - 1;
n.level = t.level + 1;
q.push(n);
}
}
}
// Driver code
int main()
{
int x = 4, y = 7;
cout << minOperations(x, y);
return 0;
}
Java
// Java program to find minimum
// number of steps needed to
// convert a number x into y
// with two operations allowed :
// (1) multiplication with 2
// (2) subtraction with 1.
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
class GFG {
int val;
int steps;
public GFG(int val, int steps)
{
this.val = val;
this.steps = steps;
}
}
public class GeeksForGeeks {
private static int minOperations(int src, int target)
{
Set visited = new HashSet<>(1000);
LinkedList queue = new LinkedList();
GFG node = new GFG(src, 0);
queue.offer(node);
visited.add(node);
while (!queue.isEmpty()) {
GFG temp = queue.poll();
visited.add(temp);
if (temp.val == target) {
return temp.steps;
}
int mul = temp.val * 2;
int sub = temp.val - 1;
// given constraints
if (mul > 0 && mul < 1000) {
GFG nodeMul = new GFG(mul, temp.steps + 1);
queue.offer(nodeMul);
}
if (sub > 0 && sub < 1000) {
GFG nodeSub = new GFG(sub, temp.steps + 1);
queue.offer(nodeSub);
}
}
return -1;
}
// Driver code
public static void main(String[] args)
{
// int x = 2, y = 5;
int x = 4, y = 7;
GFG src = new GFG(x, y);
System.out.println(minOperations(x, y));
}
}
// This code is contributed by Rahul
Python3
# Python3 program to find minimum number of
# steps needed to convert a number x into y
# with two operations allowed :
# (1) multiplication with 2
# (2) subtraction with 1.
import queue
# A node of BFS traversal
class node:
def __init__(self, val, level):
self.val = val
self.level = level
# Returns minimum number of operations
# needed to convert x into y using BFS
def minOperations(x, y):
# To keep track of visited numbers
# in BFS.
visit = set()
# Create a queue and enqueue x into it.
q = queue.Queue()
n = node(x, 0)
q.put(n)
# Do BFS starting from x
while (not q.empty()):
# Remove an item from queue
t = q.get()
# If the removed item is target
# number y, return its level
if (t.val == y):
return t.level
# Mark dequeued number as visited
visit.add(t.val)
# If we can reach y in one more step
if (t.val * 2 == y or t.val - 1 == y):
return t.level+1
# Insert children of t if not visited
# already
if (t.val * 2 not in visit):
n.val = t.val * 2
n.level = t.level + 1
q.put(n)
if (t.val - 1 >= 0 and t.val - 1 not in visit):
n.val = t.val - 1
n.level = t.level + 1
q.put(n)
# Driver code
if __name__ == '__main__':
x = 4
y = 7
print(minOperations(x, y))
# This code is contributed by PranchalK
C#
// C# program to find minimum
// number of steps needed to
// convert a number x into y
// with two operations allowed :
// (1) multiplication with 2
// (2) subtraction with 1.
using System;
using System.Collections.Generic;
public class GFG {
public int val;
public int steps;
public GFG(int val, int steps)
{
this.val = val;
this.steps = steps;
}
}
public class GeeksForGeeks {
private static int minOperations(int src, int target)
{
HashSet visited = new HashSet(1000);
List queue = new List();
GFG node = new GFG(src, 0);
queue.Add(node);
visited.Add(node);
while (queue.Count != 0) {
GFG temp = queue[0];
queue.RemoveAt(0);
visited.Add(temp);
if (temp.val == target) {
return temp.steps;
}
int mul = temp.val * 2;
int sub = temp.val - 1;
// given constraints
if (mul > 0 && mul < 1000) {
GFG nodeMul = new GFG(mul, temp.steps + 1);
queue.Add(nodeMul);
}
if (sub > 0 && sub < 1000) {
GFG nodeSub = new GFG(sub, temp.steps + 1);
queue.Add(nodeSub);
}
}
return -1;
}
// Driver code
public static void Main(String[] args)
{
// int x = 2, y = 5;
int x = 4, y = 7;
GFG src = new GFG(x, y);
Console.WriteLine(minOperations(x, y));
}
}
// This code is contributed by aashish1995
C++14
#include
using namespace std;
int min_operations(int x, int y) {
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y & 1)
return 1 + min_operations(x, y + 1);
// If y is even then divide it by 2 to make it closer to
// x
else
return 1 + min_operations(x, y / 2);
}
// Driver code
signed main() {
cout << min_operations(4, 7) << endl;
return 0;
}
C
#include
int min_operations(int x, int y)
{
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y & 1)
return 1 + min_operations(x, y + 1);
// If y is even then divide it by 2 to make it closer to
// x
else
return 1 + min_operations(x, y / 2);
}
// Driver code
signed main()
{
printf("%d", min_operations(4, 7));
return 0;
}
// This code is contributed by Rohit Pradhan
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG
{
static int minOperations(int x, int y)
{
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments
// required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y % 2 != 0)
return 1 + minOperations(x, y + 1);
// If y is even then divide it by 2 to make it
// closer to x
else
return 1 + minOperations(x, y / 2);
}
public static void main(String[] args)
{
System.out.println(minOperations(4, 7));
}
}
// This code is contributed by Shobhit Yadav
Python3
def min_operations(x, y):
# If both are equal then return 0
if x == y:
return 0
# Check if conversion is possible or not
if x <= 0 and y > 0:
return -1
# If x > y then we can just increase y by 1
# Therefore return the number of increments required
if x > y:
return a-b
# If last bit is odd
# then increment y so that we can make it even
if y & 1 == 1:
return 1+min_operations(x, y+1)
# If y is even then divide it by 2 to make it closer to x
else:
return 1+min_operations(x, y//2)
# Driver code
print(min_operations(4, 7))
C#
using System;
class GFG {
static int min_operations(int x, int y)
{
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments
// required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y % 2 == 1)
return 1 + min_operations(x, y + 1);
// If y is even then divide it by 2 to make it
// closer to
// x
else
return 1 + min_operations(x, y / 2);
}
// Driver code
public static int Main()
{
Console.WriteLine(min_operations(4, 7));
return 0;
}
}
// This code is contributed by Taranpreet
Javascript
输出 :
2
优化方案
在第二种方法中,我们将检查数字的最低位并根据该位的值做出决定。
我们不是将 x 转换为 y,而是将 y 转换为 x,并将反转操作,这将与将 x 转换为 y 所需的操作数相同。
因此, y 的反向操作将是:
- 将数字除以 2
- 将数字递增 1
C++14
#include
using namespace std;
int min_operations(int x, int y) {
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y & 1)
return 1 + min_operations(x, y + 1);
// If y is even then divide it by 2 to make it closer to
// x
else
return 1 + min_operations(x, y / 2);
}
// Driver code
signed main() {
cout << min_operations(4, 7) << endl;
return 0;
}
C
#include
int min_operations(int x, int y)
{
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y & 1)
return 1 + min_operations(x, y + 1);
// If y is even then divide it by 2 to make it closer to
// x
else
return 1 + min_operations(x, y / 2);
}
// Driver code
signed main()
{
printf("%d", min_operations(4, 7));
return 0;
}
// This code is contributed by Rohit Pradhan
Java
/*package whatever //do not write package name here */
import java.io.*;
class GFG
{
static int minOperations(int x, int y)
{
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments
// required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y % 2 != 0)
return 1 + minOperations(x, y + 1);
// If y is even then divide it by 2 to make it
// closer to x
else
return 1 + minOperations(x, y / 2);
}
public static void main(String[] args)
{
System.out.println(minOperations(4, 7));
}
}
// This code is contributed by Shobhit Yadav
Python3
def min_operations(x, y):
# If both are equal then return 0
if x == y:
return 0
# Check if conversion is possible or not
if x <= 0 and y > 0:
return -1
# If x > y then we can just increase y by 1
# Therefore return the number of increments required
if x > y:
return a-b
# If last bit is odd
# then increment y so that we can make it even
if y & 1 == 1:
return 1+min_operations(x, y+1)
# If y is even then divide it by 2 to make it closer to x
else:
return 1+min_operations(x, y//2)
# Driver code
print(min_operations(4, 7))
C#
using System;
class GFG {
static int min_operations(int x, int y)
{
// If both are equal then return 0
if (x == y)
return 0;
// Check if conversion is possible or not
if (x <= 0 && y > 0)
return -1;
// If x > y then we can just increase y by 1
// Therefore return the number of increments
// required
if (x > y)
return x - y;
// If last bit is odd
// then increment y so that we can make it even
if (y % 2 == 1)
return 1 + min_operations(x, y + 1);
// If y is even then divide it by 2 to make it
// closer to
// x
else
return 1 + min_operations(x, y / 2);
}
// Driver code
public static int Main()
{
Console.WriteLine(min_operations(4, 7));
return 0;
}
}
// This code is contributed by Taranpreet
Javascript
输出
2