From fe26f8734e3e6ad7a172d7d00c6b7a2dfd7f8842 Mon Sep 17 00:00:00 2001 From: anebz Date: Thu, 19 Sep 2019 10:12:14 +0200 Subject: [PATCH] 3.2. min function in stack --- 03. Stacks and queues/3.2. min_function.md | 99 ++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 03. Stacks and queues/3.2. min_function.md diff --git a/03. Stacks and queues/3.2. min_function.md b/03. Stacks and queues/3.2. min_function.md new file mode 100644 index 0000000..44453c0 --- /dev/null +++ b/03. Stacks and queues/3.2. min_function.md @@ -0,0 +1,99 @@ +# 3.2. Stack Min + +> Design a stack which has a function min, returning the minimum element. Push, pop and min should all operate in O(1) time. + +## First idea + +If it's supposed to be O(1) like `pop`, then just get another variable `min` in the class. But min must be updated every time a `pop` or `push` happens! I could have another function `update` to update the `min` but that's basically an appendix to `pop` and `push` so it doesn't work. If the new item to be `push`ed is lower than `min`, just update it. But what about `pop`? Then I'd have to do O(n). Either we do O(n) in time, or O(n) in space and have a stack of ordered values. + +```java +public class MyStack { + private static class StackNode { + // attributes of nodes in the stack + private T data; + private StackNode next; + + public StackNode(T data){ + this.data = data; + } + } + + // attribute of the stack + private StackNode top; + private StackNode min; + min.data = 999; + + public T pop() { + if (top == null){ + throw new EmptyStackException(); + } + T item = top.data; + top = top.next; + return item; + } + + public void push(T item) { + StackNode t = new StackNode(item); + if (item < min) { + min = item; + } + t.next = top; + top = t; + } +} +``` + +## Hints + +1. The min element doesn't change very often. Only changes when a smaller elem is added or the smallest elem is popped +2. What about storing extra data at each node? what sort of data might it be? + 1. The next bigger element? That's O(n) space like before. +3. Consider having each node know the minimum of its "substack" (all the elements beneath it, including itself). + +```java +public class MyStack { + private static class StackNode { + // attributes of nodes in the stack + private T data; + private StackNode next; + private T min; + + public StackNode(T data){ + this.data = data; + } + } + + // attribute of the stack + private StackNode top; + + public T pop() { + if (top == null){ + throw new EmptyStackException(); + } + T item = top.data; + top = top.next; + return item; + } + + public void push(T item) { + StackNode t = new StackNode(item); + // first addition to stack or smaller numbers + if (top == null || item < top.min) { + t.min = item; + } + t.next = top; + top = t; + } + + public void get_min() { + if (top == null){ + throw new EmptyStackException(); + } + return top.min; + } +} +``` + +## Solution + +Having just an integer works well except when the minimum element is popped, then it takes O(n) to update the stack. But for larger stacks, it takes a lot of space. We could create a stack of mins. [Code for solution](https://github.com/careercup/CtCI-6th-Edition/tree/master/Java/Ch%2003.%20Stacks%20and%20Queues/Q3_02_Stack_Min).