Validate subsequence
Solving this problem helped me understand the order of techniques I can explore to arrive at the solution for an array problem.
Problem statement
Given two non-empty arrays of integers, write a function that determines whether the second array is a subsequence of the first one.
A subsequence of an array is a set od numbers that aren’t necessarily adjacent in the array but that are in the same order as they appear in the array.
Understand
Input:
- array = [1,2,3,4,5,6,7,8],
- subsequence = [3,5,7] Output: true
Input:
- array: [10,20,30,40,50]
- subsequence: [40] Output: true
Input:
- array = [11,11,11,11]
- subsequence: [12,13,14] Output: false
Input:
- array: [5,1,22,25,6,-1,8,10]
- subsequence: [1,6,-1,-2] Output: false
Input:
- array: []
- subsequence: [2,4,5] Output: Invalid case
Match and Plan
List
- iterate subsequence check for the numbers of subsequence are also present in input array and are in same order
- O(n^2) solution
- NOTE: with this plan, we cannot handle the duplicate numbers in the array of in the sequence
Linked List
- complicates the solution
Sets
- with sets we cannot:
- handle the duplicate values
- maintain the order of numbers
Dictionaries
- iterate through sequence
- build a hashmap,
- if keys are numbers of the sequence and values are the index of the number in sequence
- will fail in handling duplicate numbers
- if keys are the index of the numbers in the sequence and values are the numbers themselves
- we won’t be able to check if a number in array is present in dictionary in constant time
- if keys are numbers of the sequence and values are the index of the number in sequence
Techniques
- build an array of all the possible sequence of the input array
- check if the given subsequence is present in the array of all the possible sequence of the input array
Pointers with pointers we can compare two numbers in the array and condition their movement accordingly. Pointers can also optimize the solution by not taking extra space
- initialize two index pointers to 0
- let one index pointer point to the numbers in sequence and the other to the numbers in array
- if array[array_index] == sequence[sequence_index], increment sequence_index to check the next number in the sequence
- increment array_index regardless
- return true of all the numbers in the sequence are covered
Implement
def isValidSubsequence(array, sequence):
arr_idx = 0
seq_idx = 0
while arr_idx < len(array) and seq_idx < len(sequence):
if sequence[seq_idx] == array[arr_idx]:
seq_idx += 1
arr_idx += 1
return seq_idx == len(sequence)
Review
lets dry run the code with the following test case:
array = [1,2,3], sequence = [1,3]
Evaluate
Complexity:
- time: O(n), where n = len(array)
- space: O(1)