Given an array arr of size n, where each element arr[i] represents the stock price on day i. Calculate the span of stock prices for each day.
The span Si for a specific day i is defined as the maximum number of consecutive previous days (including the current day) for which the stock price was less than or equal to the price on day i.
Input: n = 7, arr = [120, 100, 60, 80, 90, 110, 115]
Output: 1 1 1 2 3 5 6
Explanation:
Traversing the given input span:
120 is greater than or equal to 120 and there are no more elements behind it so the span is 1,
100 is greater than or equal to 100 and smaller than 120 so the span is 1,
60 is greater than or equal to 60 and smaller than 100 so the span is 1,
80 is greater than or equal to 60, 80 and smaller than 100 so the span is 2,
90 is greater than or equal to 60, 80, 90 and smaller than 100 so the span is 3,
110 is greater than or equal to 60, 80, 90, 100, 110 and smaller than 120 so the span is 5,
115 is greater than or equal to all previous elements and smaller than 120 so the span is 6.
Hence the output will be 1 1 1 2 3 5 6.
Input: n = 6, arr = [15, 13, 12, 14, 16, 20]
Output: 1 1 1 3 5 6
Explanation:
Traversing the given input span:
15 is greater than or equal to 15 and there are no more elements behind it so the span is 1,
13 is greater than or equal to 13 and smaller than 15 so the span is 1,
12 is greater than or equal to 12 and smaller than 13 so the span is 1,
14 is greater than or equal to 12, 14 and smaller than 15 so the span is 2,
16 is greater than or equal to 12, 14, 15, 16 and smaller than 20 so the span is 4,
20 is greater than or equal to all previous elements so the span is 6.
Hence the output will be 1 1 1 2 4 6.
Input: n = 8, arr = [30, 20, 25, 28, 27, 29, 35, 40]
The brute force to solve the problem is to start counting the days (for each day) where the stock prices were less than or equal to the price of stocks on current day.
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
// Function to find the span of stock prices for each day
vector <int> stockSpan(vector<int> arr, int n) {
// To store the answer
vector<int> ans(n);
// Traverse on the array
for(int i=0; i < n; i++) {
// To store the current span of stocks
int currSpan = 0;
// Traversing backwards to find stock span
for(int j=i; j >= 0; j--) {
// Update stock span
if(arr[j] <= arr[i]) {
currSpan++;
}
// Else break out from loop
else break;
}
// Store the current span
ans[i] = currSpan;
}
// Return the result
return ans;
}
};
int main() {
int n = 7;
vector<int> arr = {120, 100, 60, 80, 90, 110, 115};
/* Creating an instance of
Solution class */
Solution sol;
/* Function call to find the span
of stock prices for each day */
vector<int> ans = sol.stockSpan(arr, n);
cout << "The span of stock prices is: ";
for(int i=0; i < n; i++) {
cout << ans[i] << " ";
}
return 0;
}
import java.util.*;
class Solution {
// Function to find the span of stock prices for each day
public int[] stockSpan(int[] arr, int n) {
// To store the answer
int[] ans = new int[n];
// Traverse on the array
for(int i = 0; i < n; i++) {
// To store the current span of stocks
int currSpan = 0;
// Traversing backwards to find stock span
for(int j = i; j >= 0; j--) {
// Update stock span
if(arr[j] <= arr[i]) {
currSpan++;
}
// Else break out from loop
else break;
}
// Store the current span
ans[i] = currSpan;
}
// Return the result
return ans;
}
public static void main(String[] args) {
int n = 7;
int[] arr = {120, 100, 60, 80, 90, 110, 115};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
/* Function call to find the span
of stock prices for each day */
int[] ans = sol.stockSpan(arr, n);
System.out.print("The span of stock prices is: ");
for(int i = 0; i < n; i++) {
System.out.print(ans[i] + " ");
}
}
}
class Solution:
# Function to find the span of stock
# prices for each day
def stockSpan(self, arr, n):
# To store the answer
ans = [0] * n
# Traverse on the array
for i in range(n):
# To store the current span of stocks
currSpan = 0
# Traversing backwards to find stock span
for j in range(i, -1, -1):
# Update stock span
if arr[j] <= arr[i]:
currSpan += 1
# Else break out from loop
else:
break
# Store the current span
ans[i] = currSpan
# Return the result
return ans
# Main code
if __name__ == "__main__":
n = 7
arr = [120, 100, 60, 80, 90, 110, 115]
# Creating an instance of Solution class
sol = Solution()
# Function call to find the span
# of stock prices for each day
ans = sol.stockSpan(arr, n)
print("The span of stock prices is:", end=" ")
for span in ans:
print(span, end=" ")
class Solution {
// Function to find the span of stock prices for each day
stockSpan(arr, n) {
// To store the answer
let ans = new Array(n);
// Traverse on the array
for (let i = 0; i < n; i++) {
// To store the current span of stocks
let currSpan = 0;
// Traversing backwards to find stock span
for (let j = i; j >= 0; j--) {
// Update stock span
if (arr[j] <= arr[i]) {
currSpan++;
}
// Else break out from loop
else break;
}
// Store the current span
ans[i] = currSpan;
}
// Return the result
return ans;
}
}
// Main code
const n = 7;
const arr = [120, 100, 60, 80, 90, 110, 115];
/* Creating an instance of
Solution class */
const sol = new Solution();
/* Function call to find the span
of stock prices for each day */
const ans = sol.stockSpan(arr, n);
console.log("The span of stock prices is:", ans.join(" "));
Time Complexity: O(N2) (where N is the length of given array)
Using two nested loops.
Space Complexity: O(1)
Using only a couple of variables.
Pre Requisite: Next Greater Element
As stated in the problem, the stock span is the number of consecutive days for which the stock price was less than or equal to the price on current day. Hence, to get the stock span for current day, the aim is to find the position of its previous greater element. This will significantly improve the solution by eliminating multiple backwards traversals on the given array.
#include <bits/stdc++.h>
using namespace std;
class Solution {
private:
/* Function to find the indices of previous
greater element for each element in the array */
vector<int> findPGE(vector<int> arr) {
int n = arr.size(); //size of array
// To store the previous greater elements
vector<int> ans(n);
// Stack to get elements in LIFO fashion
stack<int> st;
// Start traversing from the front
for(int i=0; i < n; i++) {
// Get the current element
int currEle = arr[i];
/* Pop the elements in the stack until
the stack is not empty and the top
element is not the greater element */
while(!st.empty() && arr[st.top()] <= currEle) {
st.pop();
}
/* If the greater element is not
found, stack will be empty */
if(st.empty())
ans[i] = -1;
// Else store the answer
else
ans[i] = st.top();
// Push the current index in the stack
st.push(i);
}
// Return the result
return ans;
}
public:
// Function to find the span of stock prices for each day
vector <int> stockSpan(vector<int> arr, int n) {
// Get the indices of previous greater elements
vector<int> PGE = findPGE(arr);
// To store the answer
vector<int> ans(n);
// Compute the result
for(int i=0; i < n; i++) {
ans[i] = i - PGE[i];
}
// Return the result
return ans;
}
};
int main() {
int n = 7;
vector<int> arr = {120, 100, 60, 80, 90, 110, 115};
/* Creating an instance of
Solution class */
Solution sol;
/* Function call to find the span
of stock prices for each day */
vector<int> ans = sol.stockSpan(arr, n);
cout << "The span of stock prices is: ";
for(int i=0; i < n; i++) {
cout << ans[i] << " ";
}
return 0;
}
import java.util.*;
class Solution {
/* Function to find the indices of previous
greater element for each element in the array */
private int[] findPGE(int[] arr) {
int n = arr.length; //size of array
// To store the previous greater elements
int[] ans = new int[n];
// Stack to get elements in LIFO fashion
Stack<Integer> st = new Stack<>();
// Start traversing from the front
for(int i = 0; i < n; i++) {
// Get the current element
int currEle = arr[i];
/* Pop the elements in the stack until
the stack is not empty and the top
element is not the greater element */
while(!st.isEmpty() && arr[st.peek()] <= currEle) {
st.pop();
}
/* If the greater element is not
found, stack will be empty */
if(st.isEmpty())
ans[i] = -1;
// Else store the answer
else
ans[i] = st.peek();
// Push the current index in the stack
st.push(i);
}
// Return the result
return ans;
}
// Function to find the span of stock prices for each day
public int[] stockSpan(int[] arr, int n) {
// Get the indices of previous greater elements
int[] PGE = findPGE(arr);
// To store the answer
int[] ans = new int[n];
// Compute the result
for(int i = 0; i < n; i++) {
ans[i] = i - PGE[i];
}
// Return the result
return ans;
}
public static void main(String[] args) {
int n = 7;
int[] arr = {120, 100, 60, 80, 90, 110, 115};
/* Creating an instance of
Solution class */
Solution sol = new Solution();
/* Function call to find the span
of stock prices for each day */
int[] ans = sol.stockSpan(arr, n);
System.out.print("The span of stock prices is: ");
for(int i = 0; i < n; i++) {
System.out.print(ans[i] + " ");
}
}
}
class Solution:
# Function to find the indices of previous
# greater element for each element in the array
def findPGE(self, arr):
n = len(arr) # size of array
# To store the previous greater elements
ans = [0] * n
# Stack to get elements in LIFO fashion
st = []
# Start traversing from the front
for i in range(n):
# Get the current element
currEle = arr[i]
# Pop the elements in the stack until
# the stack is not empty and the top
# element is not the greater element
while st and arr[st[-1]] <= currEle:
st.pop()
# If the greater element is not
# found, stack will be empty
if not st:
ans[i] = -1
# Else store the answer
else:
ans[i] = st[-1]
# Push the current index in the stack
st.append(i)
# Return the result
return ans
# Function to find the span of stock prices for each day
def stockSpan(self, arr, n):
# Get the indices of previous greater elements
PGE = self.findPGE(arr)
# To store the answer
ans = [0] * n
# Compute the result
for i in range(n):
ans[i] = i - PGE[i]
# Return the result
return ans
# Main code
if __name__ == "__main__":
n = 7
arr = [120, 100, 60, 80, 90, 110, 115]
# Creating an instance of Solution class
sol = Solution()
# Function call to find the span of stock prices for each day
ans = sol.stockSpan(arr, n)
print("The span of stock prices is:", end=" ")
for span in ans:
print(span, end=" ")
class Solution {
/* Function to find the indices of previous
greater element for each element in the array */
findPGE(arr) {
const n = arr.length; // size of array
// To store the previous greater elements
const ans = new Array(n).fill(0);
// Stack to get elements in LIFO fashion
const st = [];
// Start traversing from the front
for (let i = 0; i < n; i++) {
// Get the current element
const currEle = arr[i];
/* Pop the elements in the stack until
the stack is not empty and the top
element is not the greater element */
while (st.length && arr[st[st.length - 1]] <= currEle) {
st.pop();
}
/* If the greater element is not
found, stack will be empty */
if (st.length === 0)
ans[i] = -1;
// Else store the answer
else
ans[i] = st[st.length - 1];
// Push the current index in the stack
st.push(i);
}
// Return the result
return ans;
}
// Function to find the span of stock prices for each day
stockSpan(arr, n) {
// Get the indices of previous greater elements
const PGE = this.findPGE(arr);
// To store the answer
const ans = new Array(n).fill(0);
// Compute the result
for (let i = 0; i < n; i++) {
ans[i] = i - PGE[i];
}
// Return the result
return ans;
}
}
// Main code
const n = 7;
const arr = [120, 100, 60, 80, 90, 110, 115];
/* Creating an instance of
Solution class */
const sol = new Solution();
/* Function call to find the span
of stock prices for each day */
const ans = sol.stockSpan(arr, n);
console.log("The span of stock prices is:", ans.join(" "));
Time Complexity: O(N)
Space Complexity: O(N)
The stack space used to find the previous greater elements can go up to O(N) in the worst case.
Q: Why do we store indices instead of prices in the stack?
A: Storing indices allows us to directly compute the span as the difference between indices.
Q: How does this problem relate to Next Greater Element (NGE) problems?
A: Both use monotonic stacks but in opposite order (NGE finds the next larger element, while this finds the previous smaller element).
Q: How does this problem relate to Next Greater Element (NGE) problems?
A: Both use monotonic stacks but in opposite order (NGE finds the next larger element, while this finds the previous smaller element).