我正在尝试以面向对象的方式编写代码。在这种特殊情况下,我想在O(1)时间内跟踪堆栈的最小值。我知道怎么做,它的想法,以及我对它的想法,就是有另一个堆栈来跟踪每次推送和弹出的最小值。
我已经嵌套了程序类中的每个类,这个类叫做 minStack ,但是当我创建一个minStack实例并调用它的变量时,这似乎不是正确的做法对于常规堆栈来说效果很好。我创建了一个扩展一个名为 StackWithMin 的 Stack 的类,但我不知道如何调用它的值。我应该创建StackWithMin的新实例吗?如果是这样我怎么办?我在main函数上面的代码末尾做了它,但是peek()总是返回null
class minStack {
public class Stack {
Node top;
Object min = null;
Object pop() {
if(top != null) {
Object item = top.getData();
top = top.getNext();
return item;
}
return null;
}
void push(Object item) {
if(min == null) {
min = item;
}
if((int)item < (int)min) {
min = item;
}
Node pushed = new Node(item, top);
top = pushed;
}
Object peek() {
if(top == null) {
//System.out.println("Its null or stack is empty");
return null;
}
return top.getData();
}
Object minimumValue() {
if(min == null) {
return null;
}
return (int)min;
}
}
public class Node {
Object data;
Node next;
public Node(Object data) {
this.data = data;
this.next = null;
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public void setNext(Node n) {
next = n;
}
public Node getNext() {
return next;
}
public void setData(Object d) {
data = d;
}
public Object getData() {
return data;
}
}
public class StackWithMin extends Stack {
Stack s2;
public StackWithMin() {
s2 = new Stack();
}
public void push(Object value) {
if((int)value <= (int)min()) {
s2.push(value);
}
super.push(value);
}
public Object pop() {
Object value = super.pop();
if((int)value == (int)min()) {
s2.pop();
}
return value;
}
public Object min() {
if(s2.top == null) {
return null;
}
else {
return s2.peek();
}
}
}
Stack testStack = new Stack();
StackWithMin stackMin = new StackWithMin();
public static void main(String[] args) {
minStack mStack = new minStack();
//StackWithMin stackMin = new StackWithMin();
mStack.testStack.push(3);
mStack.testStack.push(5);
mStack.testStack.push(2);
mStack.stackMin.push(2);
mStack.stackMin.push(4);
mStack.stackMin.push(1);
System.out.println(mStack.testStack.peek());
System.out.println(mStack.stackMin.peek());
mStack.testStack.pop();
}
}
答案 0 :(得分:1)
我建议像这样创建通用接口JLabel jl = new JLabel("asdfasdfasdf");
jl.setForeground(Color.RED);
JScrollPane scroll = new JScrollPane();
// I Have tried
jl.setBackground(new Color(0, 0, 0, 255));
scroll.setBackground(new Color(0, 0, 0, 255));
scroll.setOpaque(true);
scroll.setVisible(true);
scroll.setRowHeaderView(jl);
Stack
泛型通过制造更多错误来增加代码的稳定性 在编译时可检测到。
详细了解generics here。
然后以通用方式实现此接口。所有实现细节都将隐藏在此类(例如您的interface Stack<T> {
void push(T item);
T pop();
T peek();
}
类)中。这是代码(它只是为了展示这个想法,如果你想使用它,你需要通过异常处理来改进它)。请注意,类Node
现在也是通用的。
Node
现在我们到达存储最小值的部分。我们可以扩展我们的class SimpleStack<T> implements Stack<T> {
private class Node<T> { ... }
private Node<T> root = null;
public void push(T item) {
if (root == null) {
root = new Node<T>(item);
} else {
Node<T> node = new Node<T>(item, root);
root = node;
}
}
public T pop() {
if (root != null) {
T data = root.getData();
root = root.getNext();
return data;
} else {
return null;
}
}
public T peek() {
if (root != null) {
return root.getData();
} else {
return null;
}
}
}
类,并使用另一个SimpleStack
添加字段。但是我认为最好再进行SimpleStack
的另一个实现,并为值和最小值存储两个堆栈。示例如下。我已经推广了现在使用Stack
来比较对象的类,因此您可以使用任何其他对象类型。
Comparator
现在您可以使用这两种实现
class StackWithComparator<T> implements Stack<T> {
private Comparator<T> comparator;
private SimpleStack<T> mins = new SimpleStack<>();
private SimpleStack<T> data = new SimpleStack<>();
public StackWithComparator(Comparator<T> comparator) {
this.comparator = comparator;
}
public void push(T item) {
data.push(item);
if (mins.peek() == null || comparator.compare(mins.peek(), item) >= 0) {
mins.push(item);
} else {
mins.push(mins.peek());
}
}
public T pop() {
mins.pop();
return data.pop();
}
public T peek() {
return data.peek();
}
public T min() {
return mins.peek();
}
}