Here will show the thinking flow from bad to good.
idea 1:
const int MAX_INT = ~(1<<31);//2147483647
struct node{
int val, min;
};
class StackWithMin{
public:
StackWithMin(int size){
buf = new node[size];
buf[0].min = MAX_INT;
cur = 0;
}
~StackWithMin(){
delete[] buf;
}
void push(int val){
buf[++cur].val = val;
//buf[ptop].min = (val > buf[--ptop].min)?buf[--ptop].min:val;
buf[cur].min = (val>(buf[cur-1].min))?buf[cur-1].min:val;
}
void pop(){
--cur;
}
int top(){
return buf[cur].val;
}
bool empty(){
return cur==0;
}
int min(){
return buf[cur].min;
}
void print(){
while(--cur){
cout << buf[cur].val << ", ";
}
}
private:
node *buf;
int cur;
};
new[] 在这里是“
use the array form of new and delete (often called new[] and delete[]):”
而“buf是用来access这个node型的array的”, 所以“
Note that array access is done the same way with dynamically allocated arrays as with normal arrays. While this might look slightly funny, given that pnArray is explicitly declared as a pointer, remember that arrays are really just pointers in C++ anyway.”
output:
Executing the program....
$demo
0 19
20 + 20 - 20
18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 0 manhattan
-100 -100
-100 -100
ans use 2 stack instead of 1 so save more space in average.
// solution for CC150: Ch3-2.cpp
// idea 0: iterate the stack one by one, and use a min variable to store the minimum number
// this is problematic solution, for example, the poped top is the min value and then
// the min variable is not the real min value.
// idea 0.1: how about use 2 min variable? NO... Becuase if continuous pop, it won't work
// idea 1: use data structure: node(val, minTillnow), then each node has the current value
// and the min value to this node, so even pop, the rest nodes store the info about
// min, but the space = 2X(idea 1).
#include
using namespace std;
const int MAX_INT = ~(1<<31);//2147483647
struct node{
int val;
int min; // min till this node
};
class StackWithMin1{
public:
StackWithMin1(int size){
buf = new node[size];
buf[0].min = MAX_INT;
//this->ptop = -1;
ptop = 0;
}
~StackWithMin1(){
delete[] buf;
}
void push(int val){
buf[++ptop].val = val;
buf[ptop].min = (val > buf[ptop-1].min)?buf[ptop-1].min:val;
}
void pop(){
--ptop;
}
int top(){
return buf[ptop].val;
}
bool empty(){
return ptop==0;
}
int min(){
return buf[ptop].min;
}
void print(){
int ptr = this->ptop;
cout << this->ptop<<" + " <
<<" - "<< ptr << endl;
while(ptr){
cout << buf[--ptr].val << " ";
}
cout << "manhattan" << endl;
}
private:
node* buf;
int ptop;
};
// idea 2: use 2 stack, 1st to store all the nodes, 2nd to store all the min value to this node
// because push/pop is for connected nodes, so the min value will keep in order in stack1/2
class stack{
public:
stack(int size=100){
arr = new int[size];
cur = -1;
}
~stack(){
delete[] arr;
}
void push(int val){
arr[++cur] = val;
}
void pop(){
--cur;
}
int top(){
return arr[cur];
}
bool empty(){
return cur==-1;
}
void print(){
while(cur>-1){
cout << arr[cur--] << " ";
}
cout << "manhattan" << endl;
}
private:
int* arr;
int cur;
};
class StackWithMin2{
public:
StackWithMin2(){
//
}
~StackWithMin2(){
//
}
void push(int val){
s1.push(val);
if(val <= min())
s2.push(val);
}
void pop(){
if(s1.top()==min())
s2.pop();
s1.pop();
}
int top(){
return s1.top();
}
bool empty(){
return s1.empty();
}
int min(){
if(s2.empty()) return MAX_INT;
else return s2.top();
}
/*
void print(){ // how to print s1,s2?
while(s1.cur){
cout << arr[--s1.cur] << " ";
}
cout << "manhattan" << endl;
}
*/
void print(){
s1.print();
s2.print();
}
private:
stack s1,s2;
//stack s2(100);
};
int main(){
//cout<
<
Here is the final result:
Executing the program....
$demo
20 90
90 20 30 40 59 58 57 56 55 54 53 52 51 50 manhattan //s1
20 30 40 50 manhattan // s2:here shows that s2 only stack the current min value
-100 -100
-100 -100