Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LC716][C++][Stack][v1] #189

Merged
merged 2 commits into from
Jan 22, 2020
Merged

[LC716][C++][Stack][v1] #189

merged 2 commits into from
Jan 22, 2020

Conversation

xxks-kkk
Copy link
Owner

@xxks-kkk xxks-kkk commented Jan 22, 2020

Summary

Resolves: Leetcode 716

Main Techniques:

Runtime Complexity Analysis

Space Complexity Analysis

Testing

Performance

Performance Metrics from OJ Platform

Runtime: 164 ms, faster than 5.21% of C++ online submissions for Max Stack.
Memory Usage: 36.2 MB, less than 22.22% of C++ online submissions for Max Stack.

Performance Improved Since Last Change

Implementation Notice

The tricky part of the implementation is popMax(), which can be seen by the following test case:

["MaxStack","push","push","popMax","peekMax"]
[[],[5],[1],[],[]]

The correct result is

[null,null,null,5,1]

The commonly incorrect result we can get is

[null,null,null,5,5]

The root cause is once we remove the max element, we also need to update the new max element of the stack, which is tricky to do. To get implementation correctly, notice where we use pop() and push() from our own implementation rather than using the stack library implementation.

Implementation Tricks

To Do

We need to implement the test infrastructure similar to leetcode's test case, like the one shown above.

To Learn

There exists a more efficient solution. Probably this.

Questions

Language

Failure Attempts

class MaxStack
{
public:
  /** initialize your data structure here. */
  MaxStack()
  {
  }

  void push(int x)
  {
    element_with_cached_max_.emplace(ElementWithCachedMax{x, element_with_cached_max_.empty() ? x : peekMax()});
  }

  int pop()
  {
    int pop_element = element_with_cached_max_.top().element;
    element_with_cached_max_.pop();
    return pop_element;
  }

  int top()
  {
    return element_with_cached_max_.top().element;
  }

  int peekMax()
  {
    return element_with_cached_max_.top().max;
  }

  int popMax()
  {
    stack<ElementWithCachedMax> buffer;
    while (element_with_cached_max_.top().element != element_with_cached_max_.top().max)
    {
      buffer.emplace(element_with_cached_max_.top());
      element_with_cached_max_.pop();
    }
    int pop_max = element_with_cached_max_.top().element;
    element_with_cached_max_.pop();
    while (!buffer.empty())
    {
      element_with_cached_max_.emplace(buffer.top());
      buffer.pop();
    }
    return pop_max;
  }

private:
  struct ElementWithCachedMax
  {
    int element, max;
  };
  stack<ElementWithCachedMax> element_with_cached_max_;
};

The above implementation comes from EPI 8.1, which is correct if we only need peakMax() and no popMax() involved.

@xxks-kkk xxks-kkk added TwoStack Solving problem with two stacks todo Some leftover need to be done tolearn New knowledge can be learnt from labels Jan 22, 2020
@xxks-kkk xxks-kkk added this to the 1.0 milestone Jan 22, 2020
@xxks-kkk xxks-kkk merged commit 39d75df into master Jan 22, 2020
@xxks-kkk xxks-kkk deleted the 716-cpp branch January 22, 2020 06:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
todo Some leftover need to be done tolearn New knowledge can be learnt from TwoStack Solving problem with two stacks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant