#300

Longest Increasing Subsequence

Medium
ArrayBinary SearchDynamic ProgrammingBinary SearchDynamic ProgrammingGreedy Algorithms
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(n²)
O(n log n)
Space
O(1)
O(n)
💡

Intuition

Time O(n log n)Space O(n)

The optimal approach uses a combination of dynamic programming and binary search to efficiently find the longest increasing subsequence. By maintaining a list that represents the smallest tail of all increasing subsequences found so far, we can quickly determine where to place new elements.

⚙️

Algorithm

5 steps
  1. 1Step 1: Initialize an empty list 'tails' to store the smallest tail for all increasing subsequences.
  2. 2Step 2: Iterate through each number in the input array.
  3. 3Step 3: Use binary search to find the index of the current number in 'tails'.
  4. 4Step 4: If the number is larger than all elements in 'tails', append it. Otherwise, replace the found index with the current number.
  5. 5Step 5: The length of 'tails' will be the length of the longest increasing subsequence.
solution.py12 lines
1# Full working Python code
2import bisect
3
4def lengthOfLIS(nums):
5    tails = []
6    for num in nums:
7        index = bisect.bisect_left(tails, num)
8        if index == len(tails):
9            tails.append(num)
10        else:
11            tails[index] = num
12    return len(tails)

Complexity note: The time complexity is O(n log n) due to the binary search operation for each element in the array, while the space complexity is O(n) for storing the 'tails' list.

  • 1The longest increasing subsequence can be efficiently found using binary search.
  • 2Maintaining a list of smallest tails helps in optimizing the search for subsequences.

Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.