【问题标题】:Check if a stack is palindrome检查堆栈是否是回文
【发布时间】:2020-12-19 00:50:22
【问题描述】:

在最近的一次编码面试中,我被要求解决一个问题,其中任务是完成一个函数,该函数通过引用接收堆栈作为参数,并检查传递的堆栈是否为回文。我确实想出了一个方法,但在我看来这根本不是一个好方法。

我的代码

#include <iostream>
#include <vector>
#include <stack>
using namespace std;

void copy_it(stack<int> &st, stack<int> &temp) {
    if(st.empty())
        return;
    int element = st.top();
    temp.push(element);
    st.pop();
    copy_it(st, temp);
    st.push(element);
}
bool check_palindrome(stack<int> &st, stack<int> &temp) {
    if(st.size() != temp.size())
        return false;
    while(!st.empty()) {
        if(st.top() != temp.top())
            return false;
        st.pop();
        temp.pop();
    }
    return true;
}
int main()
{
    vector<int>vec{-1, -2, -3, -3, -2, -1};
    stack<int>st;
    for(int i = vec.size() - 1; i >= 0; --i) {
        st.push(vec[i]);
    }
    stack<int> temp;
    copy_it(st, temp);
    cout << check_palindrome(st, temp);
   return 0;
} 

有没有更好的方法来做到这一点?我最好寻找递归算法/代码。

【问题讨论】:

    标签: c++ algorithm stack palindrome stdstack


    【解决方案1】:

    一种方法是弹出一半的堆栈,压入另一个堆栈并比较它们。例如:

       [A, B, C, B, A]       // our stack, where right is top
    -> [A, B, C, B], [A]     // pop A, push A onto temporary stack
    -> [A, B, C], [A, B]     // pop B, push B
    -> [A, B], [A, B]        // pop C, discard C
    

    仅当堆栈大小为奇数时,我们必须弹出回文的中心 (C) 作为最后一步。

    bool isPalindrome(std::stack<int> &stack) {
        std::stack<int> tmp;
        size_t size = stack.size();
        size_t halfSize = size / 2;
        for (size_t i = 0; i < halfSize; ++i) {
            tmp.push(stack.top());
            stack.pop();
        }
        // discard leftover element if the number of original elements is odd
        if (size & 1) {
            stack.pop();
        }
        return tmp == s;
    }
    

    如果应该恢复原始堆栈的状态,我们只需通过从我们的tmp 堆栈弹出并推回输入stack 来反转该过程。请记住,我们不会丢弃中间元素,而是在将其推回之前暂时存储它。

    或者,如果这不被认为是“作弊”,我们可以简单地接受stack 作为值而不是左值引用。然后我们在进行任何更改之前复制它。

    替代递归实现

    // balance() does the job of popping from one stack and pushing onto
    // another, but recursively.
    // For simplicity, it assumes that a has more elements than b.
    void balance(std::stack<int> &a, std::stack<int> &b) {
        if (a.size() == b.size()) {
            return;
        }
        if (a.size() > b.size()) {
            b.push(a.top());
            a.pop(); 
            if (a.size() < b.size()) {
                // we have pushed the middle element onto b now
                b.pop();
                return;
            }
        }
        return balance(a, b);
    }
    
    bool isPalindrome(std::stack<int> &stack) {
        std::stack<int> tmp;
        balance(stack, tmp);
        return stack == tmp;
    }
    

    【讨论】:

      【解决方案2】:
      bool check_palindrome(std::stack<int> &st) {
          std::stack<int> temp;
          auto initialSize = st.size();
          for(size_t i{}; i < initialSize/2; ++i) { temp.push(st.top()); st.pop(); }
          if(temp.size() < st.size()) st.pop();
          return st == temp;
      }
      

      【讨论】:

      • 这个解决方案似乎改变了原始堆栈的内容,这可能会或可能不会被禁止。
      • @SamVarshavchik 通过引用而不是 const 引用表示的操作。如果堆栈希望为 const,则操作可以获取副本
      • 在问题本身中,工作完成后,堆栈的原始内容被恢复。堆栈可修改可能是也可能不是要求,但它的内容应该在工作完成后留下。
      【解决方案3】:

      我认为您在这里不需要递归算法,只需将堆栈中的一半元素压入第二个堆栈,然后弹出两个堆栈的元素并检查它们是否相同:

      int main()
      {
          vector<int>vec{-1, -2, -3, -3, -2, -1};
          stack<int>st;
          for(int i = vec.size() - 1; i >= 0; --i) {
              st.push(vec[i]);
          }
          stack<int> temp;
          for (size_t i = 0; i < st.size() / 2; i++)
          {
            temp.push(st.top());
            st.pop();
          }
          if (st.size() != temp.size()) st.pop();
          while (!st.empty())
          {
            if (st.top() != temp.top()) return 1;
            st.pop();
            temp.pop();
          }
          return 0;
      } 
      

      【讨论】:

        猜你喜欢
        • 2013-06-18
        • 1970-01-01
        • 2021-12-08
        • 2013-07-26
        • 2013-12-06
        • 2021-04-28
        • 2012-03-16
        • 1970-01-01
        • 2019-09-17
        相关资源
        最近更新 更多