WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Dynamic Programming · Intermediate · question 33 of 100

Solve the Longest Bitonic Subsequence problem using dynamic programming.?

📕 Buy this interview preparation book: 100 Dynamic Programming questions & answers — PDF + EPUB for $5

The Longest Bitonic Subsequence problem asks us to find the longest subsequence of an input sequence that first increases and then decreases.

Dynamic programming is a good fit for this problem since we can break it down into smaller subproblems and use the solutions to these subproblems to solve the overall problem.

We can approach this problem using two dynamic programming arrays - one to store the longest increasing subsequence ending at each index in the input sequence, and another to store the longest decreasing subsequence starting at each index in the input sequence.

Let’s call the input sequence ‘arr‘ of length ‘n‘. We can initialize both arrays to have a length of ‘n‘ and all values to be 1, since the longest increasing/decreasing subsequence at any index will always be at least 1 (the element itself).

To compute the longest increasing subsequence for each index in ‘arr‘, we can iterate through the array from left to right and compare the value at each index to all the values to its left. If ‘arr[i] > arr[j]‘ (where ‘j‘ is any index to the left of ‘i‘), we can update the longest increasing subsequence ending at ‘arr[i]‘ to be the maximum value of ‘lis[j] + 1‘ (the longest increasing subsequence ending at ‘arr[j]‘ plus one for ‘arr[i]‘ itself) and the current value of ‘lis[i]‘. Essentially, we are asking - if I include the element at index ‘i‘, what is the longest increasing subsequence that I can form up to this point?

Similarly, to compute the longest decreasing subsequence for each index in ‘arr‘, we can iterate through the array from right to left and compare the value at each index to all the values to its right. If ‘arr[i] > arr[j]‘ (where ‘j‘ is any index to the right of ‘i‘), we can update the longest decreasing subsequence starting at ‘arr[i]‘ to be the maximum value of ‘lds[j] + 1‘ (the longest decreasing subsequence starting at ‘arr[j]‘ plus one for ‘arr[i]‘ itself) and the current value of ‘lds[i]‘. Essentially, we are asking - if I include the element at index ‘i‘, what is the longest decreasing subsequence that I can form starting from this point?

Finally, we can compute the longest bitonic subsequence by iterating through ‘arr‘ and finding the maximum value of ‘lis[i] + lds[i] - 1‘. Note that we subtract one since we are double counting the value at index ‘i‘.

Here is the Java code implementation of the Longest Bitonic Subsequence problem using dynamic programming:

public static int longestBitonicSubsequence(int[] arr) {
    int n = arr.length;
    int[] lis = new int[n];
    int[] lds = new int[n];

    // initialize both arrays to have a length of n and all values to be 1
    Arrays.fill(lis, 1);
    Arrays.fill(lds, 1);

    // compute the longest increasing subsequence for each index in arr
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (arr[i] > arr[j]) {
                lis[i] = Math.max(lis[i], lis[j] + 1);
            }
        }
    }

    // compute the longest decreasing subsequence for each index in arr
    for (int i = n - 2; i >= 0; i--) {
        for (int j = n - 1; j > i; j--) {
            if (arr[i] > arr[j]) {
                lds[i] = Math.max(lds[i], lds[j] + 1);
            }
        }
    }

    int maxBitonicLength = 0;
    // compute the longest bitonic subsequence by finding the maximum value of lis[i] + lds[i] - 1
    for (int i = 0; i < n; i++) {
        maxBitonicLength = Math.max(maxBitonicLength, lis[i] + lds[i] - 1);
    }

    return maxBitonicLength;
}

Let’s say we have ‘arr = 1, 11, 2, 10, 4, 5, 2, 1‘. This sequence has a longest bitonic subsequence of length 6, which is 1, 2, 10, 5, 2, 1. We can verify that this code returns the correct answer:

int[] arr = {1, 11, 2, 10, 4, 5, 2, 1};
int longestBitonicLength = longestBitonicSubsequence(arr);
System.out.println(longestBitonicLength); // Output: 6
Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Dynamic Programming interview — then scores it.
📞 Practice Dynamic Programming — free 15 min
📕 Buy this interview preparation book: 100 Dynamic Programming questions & answers — PDF + EPUB for $5

All 100 Dynamic Programming questions · All topics