Minimise moves to reduce N to 0 using given operations

• Last Updated : 03 Dec, 2021

Given a number N, and some operations that can be performed, the task is to find the minimum number of moves to convert N to 0. In one move operation, one of the following can be performed:

• Increment or decrement the value of N by 1.
• Multiply the value of N by -1.
• Divide the value of N by 2 if N is even.
• Reduce the value of N to √N if N is a perfect square.

Example:

Input: N = 50
Output: 6
Explanation: The moves performed are: 50 (/2) -> 25 (√) -> 5 (- 1) -> 4 (/2) -> 2 (-1) -> 1 (-1) -> 0. Therefore, the required number of moves is 6 which is the minimum possible.

Input: N = 75
Output: 8

Approach: The given problem can be solved efficiently by using dynamic programming. The idea is to use hashing and breadth-first search on 0 till N is reached. Hashing is used so that the same number is not visited twice. The below steps can be followed to solve the problem:

• Use BFS by adding all the possible numbers that can be reached from 0 into a queue and also in a hashmap so that they are not visited again
• Return the number of moves calculated after reaching N.

Below is the implementation of the above approach:

C++

 // C++ code for the above approach#include using namespace std;     class Node {     public:        int val, moves;         // Constructor        Node(int v, int m)        {             val = v;            moves = m;        }    };     // Function to calculate    // minimum number of moves    // required to convert N to 0    int minMoves(int N)    {         // Initialize a hashset        // to mark the visited numbers        set set;         // Initialize a queue        queue q ;         // Mark 0 as visited        set.insert(0);         // Add 0 into the queue        q.push(new Node(0, 0));         // while N is not reached        while (!q.empty()) {             // poll out current node            Node *curr = q.front();            q.pop();             // If N is reached            if (curr->val == N) {                 // Return the number of moves used                return curr->moves;            }             if (set.find(curr->val - 1)==set.end()) {                 // Mark the number as visited                set.insert(curr->val - 1);                 // Add the number in the queue                q.push(new Node(curr->val - 1,                               curr->moves + 1));            }            if (set.find(curr->val + 1)==set.end()) {                 // Mark the number as visited                set.insert(curr->val + 1);                 // Add the number in the queue                q.push(new Node(curr->val + 1,                               curr->moves + 1));            }            if (set.find(curr->val * 2)==set.end()) {                 // Mark the number as visited                set.insert(curr->val * 2);                 // Add the number in the queue                q.push(new Node(curr->val * 2,                               curr->moves + 1));            }            int sqr = curr->val * curr->val;            if (set.find(sqr)==set.end()) {                 // Mark the number as visited                set.insert(sqr);                 // Add the number in the queue                q.push(new Node(sqr,                               curr->moves + 1));            }            if (set.find(-curr->val)==set.end()) {                 // Mark the number as visited                set.insert(-curr->val);                 // Add the number in the queue                q.push(new Node(-curr->val,                               curr->moves + 1));            }        }         return -1;    }     // Driver code     int main()    {         int N = 50;         // Call the function        // and print the answer        cout<<(minMoves(N));    } // This code is contributed by Potta Lokesh

Javascript


Output
6

Time Complexity: O(log N)
Auxiliary Space: O(K*log N), where K is the possible operations allowed

My Personal Notes arrow_drop_up