Stock Span Problem

In this tutorial, we will write the Python program for the stock span problem. It is quite popular programming problem that is frequently asked in technical interviews. The stock span problem is a financial challenge that involves analyzing a series of N daily price quotes for a particular stock. The objective is to determine the span of the stock's price for each of the N days. The span Si for a given day i represent the maximum number of consecutive days immediately preceding the current day, where the stock's price was lower than or equal to its price on the given day.

Example -

Input: N = 7, price = [100 80 60 70 60 75 85]

Output: 1 1 1 2 1 4 6

Explanation: Traversing the given input span for 100 will be 1, 80 is smaller than 100 so the span is 1, 60 is smaller than 80 so the span is 1, 70 is greater than 60 so the span is 2 and so on. Hence the output will be 1 1 1 2 1 4 6.

Input: N = 6, price = [10 4 5 90 120 80]

Output: 1 1 2 4 5 1

Explanation: Traversing the given input span for 10 will be 1, 4 is smaller than 10 so the span will be 1, 5 is greater than 4 so the span will be 2 and so on. Hence, the output will be 1 1 2 4 5 1.

To solve this problem, we will use the Naïve approach

Solution -

First, we use the naïve approach. To solve the stock span problem, we can traverse the input price array. For each element being visited, we iterate through the elements on its left side and increment the span value of the current element as long as the elements on the left side are smaller than or equal to it.

Example -

Output:

[1, 1, 2, 4, 5, 1]

Explanation -

In the above code, we define the getSpan() function that calculates the span values for a given price array.

  1. Initialize an empty array S with None values, which will store the span values.
  2. Assign the first element of S as 1, as the span value of the first day is always 1.
  3. Iterate through the price array from the second element (i = 1) to the last element (n-1).
  4. Set the span value of the current day (S[i]) as 1 initially.
  5. Initialize a variable j to i - 1, representing the index of the previous day.
  6. Enter a while loop that continues until j is greater than or equal to 0 and the price of the current day (price[i]) is greater than or equal to the price of the previous day (price[j]).
  7. Within the while loop, increment the span value of the current day (S[i]) by 1 and decrement j by 1 to move to the previous day.
  8. Once the while loop exits, the span value for the current day (S[i]) has been calculated.
  9. Repeat steps 5-8 for the remaining days.
  10. Return the array S containing the span values

The time complexity of the above code is O(n2) and auxiliary space is O(n).

Method - 2 Using Stack

In this approach, first we create an empty stack int type and push 0 in it. Now, we set the default value 1 to day 1 and iterate the rest of the days. While the stack is not empty and the price of st.top is less than or equal to the price of the current day, pop out the top value. Now, assign the value of the current day as i+1 if stack is empty else equal to i - st.top. Push the current day into the stack and print the result. Let's understand the following example.

Note - We will not pop from the stack when the current and previous stock prices are same

Example -

Output:

[1, 1, 2, 4, 5, 1, 0]

Explanation -

In the above code, we define the getSpan() function takes two arguments: price (a list of stock prices) and S (not used in the code and should be removed).

  1. The variable n is assigned the length of the price list. Then we initialize an empty stack st is initialized using a list.
  2. The first element (0) is pushed onto the stack st as a starting point.
  3. An empty list S is created with a length of n+1. This list will store the stock spans for each day.
  4. The first element of S is assigned as 1 because there are no previous days to compare with the first day.
  5. The for loop iterates over the range from 1 to n-1, representing the days from the second day to the last day.
  6. Inside the loop, a while loop is used to check if the stack is not empty and the price at the top of the stack (indexed by st[-1]) is less than or equal to the current day's price (price[i]).
  7. If the condition is true, it means the stock prices on the previous days are smaller or equal to the current day's price. Therefore, we pop the top element from the stack until the condition becomes false.
  8. After the while loop ends, S[i] is assigned the value i + 1 if the stack is empty (i.e., all previous stock prices were smaller) or (i - st[-1]) (the difference between the current day's index and the index of the top element of the stack) if the stack is not empty.
  9. The index i is pushed onto the stack st.
  10. After the loop finishes, the stock spans list S is returned.

The time complexity of the above approach is O(N) and the auxiliary space is O(N).

Method -3 Using Dynamic Programming

In this approach, we will store the value of every index and calculate the value of the next index using the previous value. Now, we will check the value of the previous element and if the value of the current element is greater than the previous element. We will add the value of the previous into the current index and check the value of (previous index -value of previous index) and check the condition repeatedly. Let's understand the following example.

Example -

Output:

[1, 1, 2, 4, 5, 1, 0]

Explanation -

In the above code, we create the getSpan() function that takes two parameters: price (a list of stock prices) and S (initially an empty list, but will be used to store the spans).

  1. We get the n the length of the price list.
  2. Then we create a new list S of length n+1 with all elements initialized to 0. This list will store the spans.
  3. The first element of S is set to 1, indicating the span for the first day is always 1.
  4. A loop is started from index 1 to index n-1 (excluding the first and last elements).
  5. Inside the loop, a counter variable is initialized to 1.
  6. A while loop is started to calculate the span for the current day. The condition checks if there are previous days (i.e., i-counter is not negative) and if the price of the current day is greater than or equal to the price of the previous day (price[i] >= price[i - counter]).
  7. If the condition is satisfied, the counter is increased by the value of S[i - counter]. It is done to skip the days whose spans have already been calculated.
  8. Once the while loop ends, the calculated span (counter) is assigned to S[i].
  9. After the loop ends, the function returns the S list, which contains the spans for each day.

Method - 4: Using two Stacks

In this approach, we will use the two stacks where one stack stores the actual stock prices whereas; the other stack is a temporary stack. Let's understand the following example.

Example -

Output:

[1, 1, 2, 4, 5, 1]

The time complexity of this approach is O(N) and auxiliary space is O(N).

Conclusion

In this tutorial, we have discussed various approaches to solving the stock span problem.