Reputation: 41
I'm working on a problem where I need to implement a recursive function in Python to find the length of the longest increasing subsequence from a list of numbers. The list can have any length and can contain any integers. I'm only allowed to use the len()
function and recursion to solve this problem, no loops, max(), helper functions or any other built-in functions are allowed.
Here's the problem description:
Given a list of numbers, find the length of the longest subsequence that creates a series of numbers that are strictly increasing. The order of the numbers in the list must not be changed to produce the increasing sequence, but numbers can be omitted.
For example, given the list [1, 5, 3, 4], the longest increasing subsequence is [1, 3, 4], therefore the resulting length is 3.
Here is my current attempt:
def longest_seq(lst, num=0):
if not lst:
return num
if len(lst) == 1:
return num + 1
if lst[0] < lst[1]:
return longest_seq(lst[1:], num + 1)
if lst[0] >= lst[1]:
if lst[0] < lst[2]:
return longest_seq([lst[0]] + lst[2:], num)
else:
return longest_seq(lst[1:], num)
The function seems to work for some inputs, but I believe the logic is flawed. I've tried to address these issues, but I'm finding it challenging to come up with a solution that only uses recursion and len(), and doesn't modify the input list.
I understand that when lst[0] >= lst[1], my function should consider two possibilities:
But I'm struggling to implement this logic in my function. Can anyone suggest how I could improve my current implementation to handle these cases correctly?
Thank you in advance for your help.
** Apologies for any confusion caused. I removed the part where I mentioned it was against the rules. I would like to clarify that I am a beginner, so I may make mistakes from time to time. Regarding the question, I attempted to solve it by restricting myself to using only the len() function and employing recursive calls.
Upvotes: 0
Views: 638
Reputation: 42133
The trick is to add an optional parameter to the function signature that will track the minimum value (previous included number in the sequence). The function then needs to compare the result of including versus excluding the first number when recursing with the rest of the list.
def longest_seq(L,previous=None):
if not L: return 0
included = excluded = longest_seq(L[1:],previous)
if previous is None or L[0]>previous:
included = 1 + longest_seq(L[1:],L[0])
return included if included>excluded else excluded
output:
print(longest_seq([1,5,3,4])) # 3
print(longest_seq([1,5,3,7,8,9])) # 5
print(longest_seq([8,1,5,2,7,3,9,4])) # 4
Upvotes: 1
Reputation: 231
I have tried to answer the problem with a different approach. Basically, I have taken two variable include_first
and exclude_first
which represents the length of the longest increasing subsequence that includes the first element and excluding the first element respectively. I have tried some test cases which I will include below in the post. Let me know if the following helps:
def longest_seq(lst):
if not lst:
return 0
if len(lst) == 1:
return 1
include_first = 1 + longest_seq(lst[1:]) if lst[0] < lst[1] else 0
exclude_first = longest_seq(lst[1:])
return max(include_first, exclude_first)
Test Cases:
print("Test Case 1:" ,longest_seq([1, 5, 3, 4]))
print("Test Case 2:", longest_seq([5, 2, 1, 0]))
print("Test Case 3:", longest_seq([1, 2, 3, 4, 5]))
print("Test Case 4:", longest_seq([5, 2, 8, 6, 3, 6, 9, 7]))
Output:
Test Case 1: 3
Test Case 2: 1
Test Case 3: 5
Test Case 4: 4
Upvotes: 1
Reputation: 742
Passing in a slice of the input list with the input removed is the correct idea. However, I'd suggest modifying your function so that it tracks the current largest element of the subsequence under consideration, as trying to achieve this by keeping lst[0]
as the largest element (which is what I think is you're doing) won't work in general. I've gone ahead and provided a skeleton as to how this might look but left some of the recursive calls/details blank.
def longest_seq(lst, largest = None, num = 0):
if not lst:
return num
rest = lst[1:] # the callee operates on the sublist of the lst, with lst[0] excluded
if num == 0:
include = longest_seq(rest, lst[0], 1) # In the callee, operate on rest, using lst[0] as the largest element. subsequence length is also 1 in the callee.
exclude = None # TBD - how would the recursive call for i
return None # TBD - larger between include/exclude
# num > 0 => largest entry populated
exclude = None # figure out the recursive call of not including lst[0]
if lst[0] > largest: # can include current
include = None # figure out recursive call
return None # TBD - larger between include/exclude
return exclude # could not include lst[0] in the subsequence so only exclude can be returned
Upvotes: 1