Jack Ack
Jack Ack

Reputation: 23

How to make a call of this recursive Longest Increasing Subsequence function

I'm learning about recursion. I have taken as an example the algorithm LIS (Longest increasing subsequence) which given an array:

1,2,8,3,6,4,9,5,7,10

Find the longest increasing subsequence that would be:

1,2,3,4,5,7,10

To start with an idea of the operation I was searching on google and I found that function:

public static void printLis (int [] lis, int lisIndex, int [] arr, int max) {
    if (max == 0) {
        return;
    }
    if (lis [lisIndex] == max) {
        printLis (lis, lisIndex-1, arr, max-1);
        System.out.print (arr [lisIndex] + "");
    } else {
        printLis (lis, lisIndex-1, arr, max);
    }
}

How do I call that function in my example, so that I get the indicated results?

Upvotes: 2

Views: 2973

Answers (2)

Kaidul
Kaidul

Reputation: 15915

Above code is not for calculating LIS. Its for printing the LIS elements. Also the snippet contains syntax error.

Here is a better recursive solution in Java with explanation.

class LIS {

    static int max_lis_length = 0; // stores the final LIS
    static List<Integer> maxArray = new ArrayList<>();

    // Recursive implementation for calculating the LIS
    static List<Integer> _lis(int arr[], int indx)
    {
        // base case
        if (indx == 0) {
            max_lis_length = 1;
            return new ArrayList<>(Arrays.asList(arr[indx]));
        }

        int current_lis_length = 1;
        List<Integer> currList = new ArrayList<>();
        for (int i=0; i< indx; i++)
        {
            // Recursively calculate the length of the LIS ending at arr[i]
            List<Integer> subproblemList = _lis(arr, i);
            int subproblem_lis_length = subproblemList.size();

            // Check if appending arr[indx] to the LIS ending at arr[i] gives us an LIS ending at 
            // arr[indx] which is longer than the previously
            // calculated LIS ending at arr[indx]
            if (arr[i] < arr[indx] && current_lis_length < (1 + subproblem_lis_length)) {
                current_lis_length = 1 + subproblem_lis_length;
                currList = subproblemList;
            }
        }
        currList.add(arr[indx]);

        // Check if currently calculated LIS ending at
        // arr[n-1] is longer than the previously calculated
        // LIS and update max_lis_length accordingly
        if (max_lis_length < current_lis_length) {
            max_lis_length = current_lis_length;
            maxArray = currList;
        }

        return currList;
    }

    // The wrapper function for _lis()
    static int lis(int arr[], int n)
    {    
        // max_lis_length is declared static above 
        // so that it can maintain its value
        // between the recursive calls of _lis()
        List<Integer> r = _lis( arr, n );
        System.out.println(r);

        return max_lis_length;
    }

    // Driver program to test the functions above
    public static void main(String args[]) {        
        int arr[] = {10, 22, 9, 33, 21, 50, 41, 60};
        int n = arr.length;
        System.out.println(lis( arr, n - 1));


    }
};

Output

[10, 22, 33, 50, 60]
5

Complexity

The corresponding tree due to this recursion is like this -

              lis(4)
        /        |     \
      lis(3)    lis(2)   lis(1)
     /   \        /
   lis(2) lis(1) lis(1)
   /
lis(1)

The time complexity is exponential. There will be 2^n - 1 nodes will be generated for a n sized array. Plus the space complexity is significant too as we are copying sub-problem's list in function argument. TO overcome this, dynamic programming is used.

Upvotes: 2

BacLuc
BacLuc

Reputation: 93

The result is not correct, but you can at least call the function:

/**
*
* @author lucius
*/
public class LISQuestion {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here

    int[] lis = new int[]{1,2,8,3,6,4,9,5,7,10};//empty array where LIS will be stored

    int[] arr = lis; //sequence where LIS should be searched

    int lisIndex = arr.length-1;

    int max = 10;

    printLis(lis, lisIndex, arr, max);
}

public static void printLis (int [] lis, int lisIndex, int [] arr, int max) {
    if (max == 0) {
        return;
    }
    if(lisIndex < 0){
        return;
    }
    if (lis [lisIndex] == max) {
        printLis (lis, lisIndex-1, arr, max-1);
        System.out.print (arr [lisIndex] + " ");
    } else {
        printLis (lis, lisIndex-1, arr, max);
    }

}

}

as it is Java, you always need a main method as entry point of the program.

Upvotes: -1

Related Questions