LeetCode – Longest Increasing Subsequence (Java)

Given an unsorted array of integers, find the length of longest increasing subsequence.

For example, given [10, 9, 2, 5, 3, 7, 101, 18], the longest increasing subsequence is [2, 3, 7, 101]. Therefore the length is 4.

Java Solution 1 - Naive

Let max[i] represent the length of the longest increasing subsequence so far.
If any element before i is smaller than nums[i], then max[i] = max(max[i], max[j]+1).

Here is an example:

longest-increasing-subsequence-leetcode-java

public int lengthOfLIS(int[] nums) {
    if(nums==null || nums.length==0)
        return 0;
 
    int[] max = new int[nums.length];
    Arrays.fill(max, 1);
 
    int result = 1;
    for(int i=0; i<nums.length; i++){
        for(int j=0; j<i; j++){
            if(nums[i]>nums[j]){
                max[i]= Math.max(max[i], max[j]+1);
 
            }
        }
        result = Math.max(max[i], result);
    }
 
   return result;
}

Java Solution 2 - Binary Search

We can put the increasing sequence in a list.

for each num in nums
     if(list.size()==0)
          add num to list
     else if(num > last element in list)
          add num to list
     else 
          replace the element in the list which is the smallest but bigger than num

longest-increasing-subsequence-leetcode-java

public int lengthOfLIS(int[] nums) {
    if(nums==null || nums.length==0)
        return 0;
 
    ArrayList<Integer> list = new ArrayList<>(); 
 
    for(int num: nums){
        if(list.size()==0 || num>list.get(list.size()-1)){
            list.add(num);
        }else{
            int i=0; 
            int j=list.size()-1;
 
            while(i<j){
                int mid = (i+j)/2;
                if(list.get(mid) < num){
                    i=mid+1;
                }else{
                    j=mid;
                }
            }
 
            list.set(j, num);
        }
    }
 
    return list.size();
}

Note that the problem asks the length of the sequence, not the sequence itself.

The binary search solution can also be simplified by using Arrays.binarySearch() method.

public int lengthOfLIS(int[] nums) {
    int[] dp = new int[nums.length];
    int len = 0; // len of sequence
 
    for(int num: nums){
        int idx = Arrays.binarySearch(dp, 0, len, num);
 
        //if not found, return binarySearch return -insertPosition-1
        if(idx < 0){
            idx = - (idx + 1);
        }
 
        dp[idx] = num;
 
        //update len when insert position is at the end
        if(idx==len){
            len++;
        }
    }
 
    return len;
}
Category >> Algorithms  
If you want someone to read your code, please put the code inside <pre><code> and </code></pre> tags. For example:
<pre><code> 
String foo = "bar";
</code></pre>
  • Shubham Jindal

    the binary search method is wrong .
    As it is violating the insertion order ie if a small element is appearing after the larger element, then also it will be adding that element as a part of the LIS

  • ryanlr

    The 1 2 3 10 is just an intermediate result, it it not the longest sub sequence.

  • Dhaval Dave

    For input 1,2,3,7,8,4 it replaces 7 with 4 and list is 1,2,3,4,8 which is wrong. Need to alter logic.

  • AlienOnEarth

    why not use stack for nlogn solution?

  • astw

    the solution 2 is not correct.

    data:
    [ 9, 1, 3, 7, 8, 9, 5, 6, 20]

    output
    1,3,5,6,9,20

    It should be
    1,3,7,8,9,20

  • Darewreck

    It’s asking for the longest sequence count, Not the actual longest sequence. The longest sequence is 4. If they where asking to print out the longest sequence, you would be correct. In that case, you would also handle the case when there two sequence with the same length.

  • TUSHAR SHARAD MHASKAR

    The binary search program fails for input 1 4 9 10 2 3
    Output produced is 1 2 3 10 which id definitely not longest increasing.