Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find length of longest sign alternating subsequence from a list of numbers in Python
Suppose we have a list of numbers called nums, we have to find the length of longest subsequence that flips sign on each consecutive number. A sign alternating subsequence means each consecutive pair of numbers has opposite signs (positive followed by negative, or negative followed by positive).
So, if the input is like nums = [1, 3, -6, 4, -3], then the output will be 4, as we can pick [1, -6, 4, -3].
Algorithm
To solve this, we will follow these steps ?
- pos := 0, neg := 0
- for each n in nums, do
- if n < 0, then
- neg := pos + 1
- otherwise,
- pos := neg + 1
- if n < 0, then
- return maximum of pos and neg
How It Works
We use two variables: pos tracks the longest subsequence ending with a positive number, and neg tracks the longest subsequence ending with a negative number. When we encounter a negative number, we can extend any positive-ending subsequence. When we encounter a positive number, we can extend any negative-ending subsequence.
Example
Let us see the following implementation to get better understanding ?
class Solution:
def solve(self, nums):
pos = neg = 0
for n in nums:
if n < 0:
neg = pos + 1
else:
pos = neg + 1
return max(pos, neg)
ob = Solution()
nums = [1, 3, -6, 4, -3]
print(ob.solve(nums))
4
Step-by-Step Execution
Let's trace through the algorithm with nums = [1, 3, -6, 4, -3] ?
def solve_with_trace(nums):
pos = neg = 0
print(f"Initial: pos={pos}, neg={neg}")
for i, n in enumerate(nums):
if n < 0:
neg = pos + 1
print(f"Step {i+1}: n={n} (negative), neg = pos + 1 = {neg}")
else:
pos = neg + 1
print(f"Step {i+1}: n={n} (positive), pos = neg + 1 = {pos}")
print(f" Current state: pos={pos}, neg={neg}")
result = max(pos, neg)
print(f"Final result: max({pos}, {neg}) = {result}")
return result
nums = [1, 3, -6, 4, -3]
solve_with_trace(nums)
Initial: pos=0, neg=0
Step 1: n=1 (positive), pos = neg + 1 = 1
Current state: pos=1, neg=0
Step 2: n=3 (positive), pos = neg + 1 = 1
Current state: pos=1, neg=0
Step 3: n=-6 (negative), neg = pos + 1 = 2
Current state: pos=1, neg=2
Step 4: n=4 (positive), pos = neg + 1 = 3
Current state: pos=3, neg=2
Step 5: n=-3 (negative), neg = pos + 1 = 4
Current state: pos=3, neg=4
Final result: max(3, 4) = 4
Alternative Implementation
Here's a more readable version with descriptive variable names ?
def longest_sign_alternating_subsequence(numbers):
"""Find length of longest sign alternating subsequence."""
ending_positive = 0 # Length ending with positive number
ending_negative = 0 # Length ending with negative number
for num in numbers:
if num < 0:
# Extend subsequence ending with positive
ending_negative = ending_positive + 1
else:
# Extend subsequence ending with negative
ending_positive = ending_negative + 1
return max(ending_positive, ending_negative)
# Test with different examples
test_cases = [
[1, 3, -6, 4, -3],
[-1, 2, -3, 4],
[1, 2, 3, 4],
[-1, -2, -3, -4]
]
for nums in test_cases:
result = longest_sign_alternating_subsequence(nums)
print(f"Input: {nums}")
print(f"Longest sign alternating subsequence length: {result}")
print()
Input: [1, 3, -6, 4, -3] Longest sign alternating subsequence length: 4 Input: [-1, 2, -3, 4] Longest sign alternating subsequence length: 4 Input: [1, 2, 3, 4] Longest sign alternating subsequence length: 1 Input: [-1, -2, -3, -4] Longest sign alternating subsequence length: 1
Conclusion
The algorithm uses dynamic programming with O(n) time complexity and O(1) space complexity. By tracking the longest subsequences ending with positive and negative numbers separately, we can efficiently find the optimal solution for sign alternating subsequences.
