Wednesday, October 28, 2015

Find out minimum operations required

There are three operations given:  
     op1 => divid by 3
     op2 => divide by 2
     op3 => subtract 1

Find minimal no. of operation required to convert a given no. to 1.

E.g.: To convert 10 to 1 minimum "3" operations are required as explained below
10 -> op3 = 9
9   -> op1 = 3
3   -> op1 = 1

Approach 1: Brute force
This problem can be solved using recursion. Try every possible operation till the number becomes equal to 1 and find minimum operations out of these.

class Solution {
   public static int noOfOperations(int n, int cur_op_count, int min_op_count) {

        if (cur_op_count >= min_op_count)
            return cur_op_count;  // this indicate a invalid path(not an optimal) so return
        if (n == 1) return cur_op_count;

        int size1 = Integer.MAX_VALUE;
        int size2 = Integer.MAX_VALUE;
        int size3 = Integer.MAX_VALUE;

        cur_op_count = cur_op_count + 1;

        if (n % 3 == 0)
            size1 = noOfOperations(n / 3, cur_op_count, min_op_count);
        min_op_count = Math.min(min_op_count, size1);

        if (n % 2 == 0)
            size2 = noOfOperations(n / 2, cur_op_count, min_op_count);
        min_op_count = Math.min(min_op_count, size2);

        size3 = noOfOperations(n - 1, cur_op_count, min_op_count);
        return Math.min(Math.min(size1, size2), size3);
    }

    public static void main(String[] args) {
        System.out.println(noOfOperations(22, 0, Integer.MAX_VALUE));
    }
}
Approach 2: Dynamic Programming
In brute force approach we are not storing the results so recursion will try to solve same subproblem every time. Add a temporary storage to hold the result of earlier solutions and use the same for next results.

Code below demonstrate approach 2 implementation.

class Solution {

    public static int minOperations(int input, int[] operations){
        if(input <= 1)
            return 0;
        if(operations[input] != -1)
            return operations[input];

        int divBy3=Integer.MAX_VALUE, divBy2 = Integer.MAX_VALUE;

        if(input % 3 == 0){
            divBy3 = minOperations(input/3, operations) + 1;
        }

        if(input % 2 == 0){
            divBy2 = minOperations(input/2, operations) + 1;
        }
        int sub1 = minOperations(input - 1, operations) + 1;

        int min = Math.min(Math.min(divBy3, divBy2), sub1);
        operations[input] = min;
        return min;
    }

    public static void main(String[] args) {
        int input = 11;
        int[] operations = new int[input+1];
        for(int i=0; i < operations.length; i++) operations[i] = -1;
        operations[0] = 0;
        operations[1] = 0;
        System.out.println("Min Operations : " + minOperations(input, operations));
    }
}

Comments are welcome.

No comments:

Post a Comment