#491

Non-decreasing Subsequences

Medium
ArrayHash TableBacktrackingBit ManipulationHash MapArray
LeetCode ↗

Approaches

Brute ForceOptimal
Complexity Comparison
Brute ForceOptimal Solution
Time
O(2^n)
O(2^n)
Space
O(n)
O(n)
💡

Intuition

Time O(2^n)Space O(n)

The optimal solution uses backtracking with pruning to efficiently generate non-decreasing subsequences. By avoiding unnecessary branches, we can significantly reduce the number of checks needed.

⚙️

Algorithm

3 steps
  1. 1Step 1: Initialize a set to store unique subsequences.
  2. 2Step 2: Use a backtracking function that builds subsequences while ensuring they are non-decreasing.
  3. 3Step 3: For each element, decide to include it in the current subsequence or skip it based on the last added element.
solution.py13 lines
1# Full working Python code
2from typing import List
3
4def findSubsequences(nums: List[int]) -> List[List[int]]:
5    result = set()
6    def backtrack(start, path):
7        if len(path) >= 2:
8            result.add(tuple(path))
9        for i in range(start, len(nums)):
10            if not path or path[-1] <= nums[i]:
11                backtrack(i + 1, path + [nums[i]])
12    backtrack(0, [])
13    return [list(seq) for seq in result]

Complexity note: The time complexity remains exponential due to the nature of subsequences, but the pruning significantly reduces the number of valid paths explored.

  • 1Non-decreasing subsequences can be efficiently generated using backtracking.
  • 2Using a set helps in avoiding duplicate subsequences.

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