无法理解使用 C++ STL 的 Stock 跨度的线性时间方法
Can't understand linear time method for Stock span using C++ STL
我在 geeksforgeeks 上找到了这个代码并且它有效。但是我有几个 doubts.Inthe 函数 calculateSpan(),在下一行中,while (!st.empty() && price[st.top()] < price[i])
..我们想将数组中第 i 个元素的值与堆栈顶部的元素进行比较,但是 st.top()
给出栈顶元素的 "value",而不是栈顶元素的 "index" 值,那么为什么行 price[st.top()]
仍然有效。同样在 calculateSpan() 函数的最后一行,st.push(i)
用于将当前元素推入堆栈,如前所述,但这不应该将 'i' 的值推入堆栈顶部。这段代码是如何工作的?我已经发布了完整的代码。提前致谢。
`
// a linear time solution for stock span problem
#include <iostream>
#include <stack>
using namespace std;
void calculateSpan(int price[], int n, int S[])
{
// Create a stack and push index of first element to it
stack<int> st;
st.push(0);
// Span value of first element is always 1
S[0] = 1;
// Calculate span values for rest of the elements
for (int i = 1; i < n; i++)
{
// Pop elements from stack while stack is not empty and top of
// stack is smaller than price[i]
while (!st.empty() && price[st.top()] < price[i])
st.pop();
// If stack becomes empty, then price[i] is greater than all elements
// on left of it, i.e., price[0], price[1],..price[i-1]. Else price[i]
// is greater than elements after top of stack
S[i] = (st.empty())? (i + 1) : (i - st.top());
// Push this element to stack
st.push(i);
}
}
// A utility function to print elements of array
void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
// Driver program to test above function
int main()
{
int price[] = {1, 4, 50, 90, 12, 80};
int n = sizeof(price)/sizeof(price[0]);
int S[n];
// Fill the span values in array S[]
calculateSpan(price, n, S);
// print the calculated span values
printArray(S, n);
return 0;
}
在函数 calculateSpan()
定义的 Stack st
中,我们插入天数 0,1,2,3,4,5
的索引,因此当我们看到 st.top()
给出索引时数组的 price[]
也。
如你所说:
but st.top()
gives the "value" of the element on stack top, not the "index" value of stack top
这里stack top
上元素的"value"本身就是数组price
的"index"值! 有道理吗?
while (!st.empty() && price[st.top()] < price[i])
st.pop();
所以,在上面的代码中price[st.top()] < price[i]
表示price[day-index] < price[selected day]
。请记住,我们将 day-index 压入堆栈。
而且由于我们将天索引压入堆栈 st
所以,我想最后几行现在也有意义
st.pop(i) // i=0,1,2,3,4,5
注意:永远不要忽略写在代码主体上的注释!例如,我猜你错过了那个评论!
// Create a stack and push index of first element to it
stack<int> st;
st.push(0);
希望对您有所帮助!
堆栈 st 是 int 类型元素的堆栈,因此 st.top() 给出一个 int,显然应该由 st.push( int ) 插入。这里的堆栈包含数组索引(天)。 st.top() 给出最后一个推送到 st 的数组索引,st.pop() 删除最后一个推送到 st.
不确定上述实现是否考虑了 price[ i ] > price[i-2] 且 price[i-1] < price[i] 且 < price[i - 2] 的情况。
另一种没有栈数据结构的实现:
S[0] = 1;
for (int i = 1; i < n; i++)
{
if ( price[ i ] >= price[ i - 1 ] )
{
S[ i ] = S[ i - 1 ] + 1;
for ( int j = i - S[i]; price[i] >= price[j] && j >= 0 ; j-- ) //look for prices less than price[i] but greater than price[i-1]
S[ i ] += 1;
}
else
S[ i ] = 1;
}
复杂度:
最好的情况是数组排序 T(n) = n 次。
最坏的情况是 price[i] 大于所有之前的价格并且 price[i-1] 小于或等于它之前的所有价格:
int 价格[] = {0, 1, 0, 2, 0, 3,0,4,0,5,0,6,0,7,0,8,0,9,0,10 ,0,11};// n=22
T(n)=1+2+1+4+1+6+1+8+1+10+1+12....+1+ 2 * (n/2)。
有n/2个循环形成公差为2 + n/2次的等差级数,其中只有1条指令(价格[i] <价格[i-1]的情况)。
T(n) 那么就是 n/2 + n/4 * [ ( 2*2 + 2 * ( (n/2) - 1 ) ] = n/2 + n/4 * ( 2 + n ) = n + [ (n^2) / 4 ]。这是当 n 为偶数时。当 n 为奇数时,它变为 1 + n/2 + [ (n^2) / 4 ]
我在 geeksforgeeks 上找到了这个代码并且它有效。但是我有几个 doubts.Inthe 函数 calculateSpan(),在下一行中,while (!st.empty() && price[st.top()] < price[i])
..我们想将数组中第 i 个元素的值与堆栈顶部的元素进行比较,但是 st.top()
给出栈顶元素的 "value",而不是栈顶元素的 "index" 值,那么为什么行 price[st.top()]
仍然有效。同样在 calculateSpan() 函数的最后一行,st.push(i)
用于将当前元素推入堆栈,如前所述,但这不应该将 'i' 的值推入堆栈顶部。这段代码是如何工作的?我已经发布了完整的代码。提前致谢。
`
// a linear time solution for stock span problem
#include <iostream>
#include <stack>
using namespace std;
void calculateSpan(int price[], int n, int S[])
{
// Create a stack and push index of first element to it
stack<int> st;
st.push(0);
// Span value of first element is always 1
S[0] = 1;
// Calculate span values for rest of the elements
for (int i = 1; i < n; i++)
{
// Pop elements from stack while stack is not empty and top of
// stack is smaller than price[i]
while (!st.empty() && price[st.top()] < price[i])
st.pop();
// If stack becomes empty, then price[i] is greater than all elements
// on left of it, i.e., price[0], price[1],..price[i-1]. Else price[i]
// is greater than elements after top of stack
S[i] = (st.empty())? (i + 1) : (i - st.top());
// Push this element to stack
st.push(i);
}
}
// A utility function to print elements of array
void printArray(int arr[], int n)
{
for (int i = 0; i < n; i++)
cout << arr[i] << " ";
}
// Driver program to test above function
int main()
{
int price[] = {1, 4, 50, 90, 12, 80};
int n = sizeof(price)/sizeof(price[0]);
int S[n];
// Fill the span values in array S[]
calculateSpan(price, n, S);
// print the calculated span values
printArray(S, n);
return 0;
}
在函数 calculateSpan()
定义的 Stack st
中,我们插入天数 0,1,2,3,4,5
的索引,因此当我们看到 st.top()
给出索引时数组的 price[]
也。
如你所说:
but
st.top()
gives the "value" of the element on stack top, not the "index" value of stack top
这里stack top
上元素的"value"本身就是数组price
的"index"值! 有道理吗?
while (!st.empty() && price[st.top()] < price[i])
st.pop();
所以,在上面的代码中price[st.top()] < price[i]
表示price[day-index] < price[selected day]
。请记住,我们将 day-index 压入堆栈。
而且由于我们将天索引压入堆栈 st
所以,我想最后几行现在也有意义
st.pop(i) // i=0,1,2,3,4,5
注意:永远不要忽略写在代码主体上的注释!例如,我猜你错过了那个评论!
// Create a stack and push index of first element to it
stack<int> st;
st.push(0);
希望对您有所帮助!
堆栈 st 是 int 类型元素的堆栈,因此 st.top() 给出一个 int,显然应该由 st.push( int ) 插入。这里的堆栈包含数组索引(天)。 st.top() 给出最后一个推送到 st 的数组索引,st.pop() 删除最后一个推送到 st.
不确定上述实现是否考虑了 price[ i ] > price[i-2] 且 price[i-1] < price[i] 且 < price[i - 2] 的情况。
另一种没有栈数据结构的实现:
S[0] = 1;
for (int i = 1; i < n; i++)
{
if ( price[ i ] >= price[ i - 1 ] )
{
S[ i ] = S[ i - 1 ] + 1;
for ( int j = i - S[i]; price[i] >= price[j] && j >= 0 ; j-- ) //look for prices less than price[i] but greater than price[i-1]
S[ i ] += 1;
}
else
S[ i ] = 1;
}
复杂度:
最好的情况是数组排序 T(n) = n 次。
最坏的情况是 price[i] 大于所有之前的价格并且 price[i-1] 小于或等于它之前的所有价格:
int 价格[] = {0, 1, 0, 2, 0, 3,0,4,0,5,0,6,0,7,0,8,0,9,0,10 ,0,11};// n=22
T(n)=1+2+1+4+1+6+1+8+1+10+1+12....+1+ 2 * (n/2)。
有n/2个循环形成公差为2 + n/2次的等差级数,其中只有1条指令(价格[i] <价格[i-1]的情况)。
T(n) 那么就是 n/2 + n/4 * [ ( 2*2 + 2 * ( (n/2) - 1 ) ] = n/2 + n/4 * ( 2 + n ) = n + [ (n^2) / 4 ]。这是当 n 为偶数时。当 n 为奇数时,它变为 1 + n/2 + [ (n^2) / 4 ]