定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的min函数。
在该栈中,调用min、push及pop的时间复杂度都是O(1).
push和pop本来都是O(1),这个不需要担心,但是获取最小值的话,
如果在栈里添加一个成员变量存放最小的元素。每次压入一个新元素进栈的时候,如果该元素比当前最小的元素还要小,则更新最小元素。
但是如果当前最小的元素被弹出栈了,如何得到下一个最小的元素呢?
分析到这里,我们发现仅仅添加一个成员变量存放最小元素是不够的,仅仅一个变量不够,也需要一个集合类型来存放这个最小元素组成的一组数据 , 也就是说当最小元素被弹出栈的时候,我们希望能够得到次小元素。因此在压入这个最小元素之前,我们要把次小元素保存起来。
保存旧值,保存历史值, 是不是可以想到又是一个栈结构, 把每次的最小元素(之前的最小元素和新压入栈的元素两者的较小值)都保存起来放到另外一个辅助栈.
好,来试一试. 这个新的结构内部有2个栈, 一个主栈,一个辅助栈.
当push的时候,主栈正常push此元素, 辅助栈push 辅助栈顶和此元素中的较小值,
当pop的时候, 主栈pop栈顶, 辅助栈也pop出栈顶元素,
当min的时候, 返回辅助栈的栈顶元素.
来个例子,
push(3),主栈和辅助栈栈顶都是3,
push(5),主栈栈顶放入5,辅助栈放入 辅助栈顶3和5的较小值 , 还是3,
push(7),主栈栈顶放入7,辅助栈放入 辅助栈顶3和7的较小值 , 还是3,
push(1),主栈栈顶放入1,辅助栈放入 辅助栈顶3和1的较小值 , 放入1,
....
当pop的时候, 主栈和辅助栈都执行pop,
...
当min的时候, 返回辅助栈的栈顶元素.
到此, 思路就完成了. 代码量不大, 但是思路很巧妙.
#import <Foundation/Foundation.h>
@interface MinStack : NSObject
- (void)push:(int)data;
- (int)pop;
- (int)min;
@end
-------------
#import "MinStack.h"
@interface MinStack ()
@property (nonatomic, strong) NSMutableArray<NSNumber *> *dataArray;
@property (nonatomic, strong) NSMutableArray<NSNumber *> *minArray;
@end
@implementation MinStack
- (instancetype)init
{
self = [super init];
if (self) {
_dataArray = [NSMutableArray array];
_minArray = [NSMutableArray array];
}
return self;
}
// 主栈进行正常的push, 辅助栈栈push一个当前的最小值
- (void)push:(int)data {
[self.dataArray addObject:@(data)];
int minValue = data ;
if (self.minArray.count>0) {
minValue = MIN(data, self.minArray.lastObject.intValue);
}
[self.minArray addObject:@(minValue)];
}
- (int)pop {
if (self.dataArray.count == 0) {
NSLog(@"栈中没有元素");
return NAN;
}
NSNumber * popNum = self.dataArray.lastObject;
[self.dataArray removeLastObject];
[self.minArray removeLastObject];
return popNum.intValue;
}
- (int)min {
if (self.minArray.count==0) {
return NAN;
}
NSLog(@"当前最小值是 %@",self.minArray.lastObject);
return self.minArray.lastObject.intValue;
}
@end