HackerRank Implement Queue using two stacks SolutionImplement data structure overflow queueSorting a Stack in ascending orderImplement MyQueue using two stacksImplement a queue using two stacksImplement queue using two stacksFinding the maximum element of a StackPushdown-stack: Test if a pop order is legal or notBefunge-93 interpreter in PythonCompute the height of a tower made of bucketsList operation while implementing stack

How did Biff return to 2015 from 1955 without a lightning strike?

How do I safety check that there is no light in Darkroom / Darkbag?

What's the term for a group of people who enjoy literary works?

Word to describe someone doing something even though told not to

What is the difference between "logical equivalence" and "material equivalence"?

What's the proper way of indicating that a car has reached its destination during a dialogue?

What does the "きゃ" in "していきゃがらなかった" stand for?

How were x-ray diffraction patterns deciphered before computers?

Protect a 6 inch air hose from physical damage

Difference between Chance constraints and logical constraints

How to draw twisted cuves?

A way of getting tenure for a non-creative person

Can I say "Gesundheit" if someone is coughing?

Word for giving preference to the oldest child

"Fewer errors means better products" or "Fewer errors mean better products"?

How to trick a fairly simplistic kill-counter?

How to power down external drive safely

Why are prop blades not shaped like household fan blades?

Can living where (rare) earth magnetic ore is abundant provide any protection from cosmic radiation?

How do I solve such questions on paramagnetism and ferromagnetism?

UX writing: When to use "we"?

Can an alphabet for a Turing machine contain subsets of other alphabets?

When did J.K. Rowling decide to make Ron and Hermione a couple?

The grades of the students in a class



HackerRank Implement Queue using two stacks Solution


Implement data structure overflow queueSorting a Stack in ascending orderImplement MyQueue using two stacksImplement a queue using two stacksImplement queue using two stacksFinding the maximum element of a StackPushdown-stack: Test if a pop order is legal or notBefunge-93 interpreter in PythonCompute the height of a tower made of bucketsList operation while implementing stack






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








3












$begingroup$


Challenge



Problem Statement - Implement a Queue using two Stacks



I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$



#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;

struct Queue
stack<int> s1,s2;

int dequeue()
int x = s1.top();
s1.pop();
return x;


void peek()
cout<< s1.top()<<"n";


void enqueue(int data)
while(!s1.empty())
s2.push(s1.top());
s1.pop();


s1.push(data);

while(!s2.empty())
s1.push(s2.top());
s2.pop();


;


int main()
int t; cin>>t;
Queue q;

while(t--)
int k; cin>>k;
switch(k)
case 1:
int x; cin>>x;
q.enqueue(x);
break;
case 2:
q.dequeue();
break;
case 3:
q.peek();


return 0;



There are 15 test cases. This code runs properly for the first 5 test cases then I get a 'Time Limit Exceeded' message for the rest of test cases.



This means the complexity of my program is too much.



So I tried reversing it, I made enqueue() as $O(1)$ and dequeue() as $O(n)$ but even that did not change anything.



What should I do to reduce time complexity of this code?










share|improve this question









New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$









  • 2




    $begingroup$
    You might get more votes and an answer if you include a description of the programming challenge.
    $endgroup$
    – pacmaninbw
    5 hours ago

















3












$begingroup$


Challenge



Problem Statement - Implement a Queue using two Stacks



I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$



#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;

struct Queue
stack<int> s1,s2;

int dequeue()
int x = s1.top();
s1.pop();
return x;


void peek()
cout<< s1.top()<<"n";


void enqueue(int data)
while(!s1.empty())
s2.push(s1.top());
s1.pop();


s1.push(data);

while(!s2.empty())
s1.push(s2.top());
s2.pop();


;


int main()
int t; cin>>t;
Queue q;

while(t--)
int k; cin>>k;
switch(k)
case 1:
int x; cin>>x;
q.enqueue(x);
break;
case 2:
q.dequeue();
break;
case 3:
q.peek();


return 0;



There are 15 test cases. This code runs properly for the first 5 test cases then I get a 'Time Limit Exceeded' message for the rest of test cases.



This means the complexity of my program is too much.



So I tried reversing it, I made enqueue() as $O(1)$ and dequeue() as $O(n)$ but even that did not change anything.



What should I do to reduce time complexity of this code?










share|improve this question









New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$









  • 2




    $begingroup$
    You might get more votes and an answer if you include a description of the programming challenge.
    $endgroup$
    – pacmaninbw
    5 hours ago













3












3








3





$begingroup$


Challenge



Problem Statement - Implement a Queue using two Stacks



I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$



#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;

struct Queue
stack<int> s1,s2;

int dequeue()
int x = s1.top();
s1.pop();
return x;


void peek()
cout<< s1.top()<<"n";


void enqueue(int data)
while(!s1.empty())
s2.push(s1.top());
s1.pop();


s1.push(data);

while(!s2.empty())
s1.push(s2.top());
s2.pop();


;


int main()
int t; cin>>t;
Queue q;

while(t--)
int k; cin>>k;
switch(k)
case 1:
int x; cin>>x;
q.enqueue(x);
break;
case 2:
q.dequeue();
break;
case 3:
q.peek();


return 0;



There are 15 test cases. This code runs properly for the first 5 test cases then I get a 'Time Limit Exceeded' message for the rest of test cases.



This means the complexity of my program is too much.



So I tried reversing it, I made enqueue() as $O(1)$ and dequeue() as $O(n)$ but even that did not change anything.



What should I do to reduce time complexity of this code?










share|improve this question









New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






$endgroup$




Challenge



Problem Statement - Implement a Queue using two Stacks



I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$



#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;

struct Queue
stack<int> s1,s2;

int dequeue()
int x = s1.top();
s1.pop();
return x;


void peek()
cout<< s1.top()<<"n";


void enqueue(int data)
while(!s1.empty())
s2.push(s1.top());
s1.pop();


s1.push(data);

while(!s2.empty())
s1.push(s2.top());
s2.pop();


;


int main()
int t; cin>>t;
Queue q;

while(t--)
int k; cin>>k;
switch(k)
case 1:
int x; cin>>x;
q.enqueue(x);
break;
case 2:
q.dequeue();
break;
case 3:
q.peek();


return 0;



There are 15 test cases. This code runs properly for the first 5 test cases then I get a 'Time Limit Exceeded' message for the rest of test cases.



This means the complexity of my program is too much.



So I tried reversing it, I made enqueue() as $O(1)$ and dequeue() as $O(n)$ but even that did not change anything.



What should I do to reduce time complexity of this code?







c++ programming-challenge stack queue






share|improve this question









New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 7 hours ago









dfhwze

7,3491 gold badge18 silver badges46 bronze badges




7,3491 gold badge18 silver badges46 bronze badges






New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 8 hours ago









KshitijV97KshitijV97

345 bronze badges




345 bronze badges




New contributor



KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




KshitijV97 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • 2




    $begingroup$
    You might get more votes and an answer if you include a description of the programming challenge.
    $endgroup$
    – pacmaninbw
    5 hours ago












  • 2




    $begingroup$
    You might get more votes and an answer if you include a description of the programming challenge.
    $endgroup$
    – pacmaninbw
    5 hours ago







2




2




$begingroup$
You might get more votes and an answer if you include a description of the programming challenge.
$endgroup$
– pacmaninbw
5 hours ago




$begingroup$
You might get more votes and an answer if you include a description of the programming challenge.
$endgroup$
– pacmaninbw
5 hours ago










2 Answers
2






active

oldest

votes


















5












$begingroup$

Algorithmic complexity for combined operations



Containers are interesting elements in most programming languages: they have an internal state, namely their elements and therefore their size.



This introduces an additional state compared to usual algorithmic asymptotical complexity analysis. For example, a naive implemented std::vector::push_back will yield $mathcal O(n^2)$ complexity if push_back increases the capacity only by one:



// pseudo-code, also very bad performance and no error handling, do not use!
void vector::push_back(T value)
if(_size == _capacity)
// has to move all elements and is therefore O(n)
reserve(_capacity + 1);

_data[_size++] = value;



While trivial, this code has a severe problem: we have to copy all elements in ever iteration. If we use push_back in a loop, we end up with a quadratic complexity.



The real push_back has therefore some tricks up in its sleeves, as the standard dictates that it will have $O(1)$ amortized complexity. More about that later in this review.



However, this small introduction should give you a hint about the central flaw in your current approach.



A hidden quadratic term




I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$




For this task, it's much more important to see the cost on both functions for $k$ enqueued elements, not a single one.



So let's envision the queue 1,2,3,4. How many steps do we need?



to enqueue 1: 
1. put `1` in `s1`
to enqueue 2:
1. move `1` from `s1` to `s2`
2. put `2` in `s1`
3. move `1` from `s2` to `s1`
- to enqueue 3:
1. move `1` from `s1` to `s2`
2. move `2` from `s1` to `s2`
3. put `3` in `s1`
4. move `2` from `s2` to `s1`
5. move `1` from `s2` to `s1`
- to enqueue 4:
1. move `1` from `s1` to `s2`
2. move `2` from `s1` to `s2`
3. move `3` from `s1` to `s2`
4. put `4` in `s1`
5. move `3` from `s2` to `s1`
6. move `2` from `s2` to `s1`
7. move `1` from `s2` to `s1`


We see that the $n$th element will take $2(n-1)$ swaps. Therefore, if we insert a total of $n$ elements into our queue, we end up with $mathcal O(n^2)$ to complete all enqueues.



We need to do better.



A better queue with two stacks



So let's get back to the drawing board. What do we need?



  1. We need to enqueue

  2. We need to dequeue

  3. We need to peek.

None of those terms indicates that we need to have all data in one stack. So first of all, we need to use better names, because s1 and s2 are pretty bland and non-descriptive:



class Queue
stack<int> in;
stack<int> out;

void flip(); // < new

public:
void enqueue(int);
int dequeue();
int peek();
;


I'll implement the methods outside of the class declaration to keep the code segments short, but you're free to place them inline again. Note that I switched from a struct to a class, because its Queues job to make sure that in and out are handled correct; no one else should be able to change them.



What will we use in and out for? Well, as long as we have elements in out, we will use them for dequeue and peek. And whatever gets enqueued gets pushed right ontop of in, no questions asked.



The critical part is how to get an element from in to out, right? I let you think about that for some paragraphs, but you may also stop here and try it yourself; the declaration above contains a clue.



So, let's have a look at my proposal for the definition of enqueue(), peek and dequeue():



void Queue::enqueue(int value) 
in.push(value);


int Queue::peek()
if (out.empty())
flip();

return out.top();


int Queue::dequeue()
if (out.empty())
flip();

int value = out.top();
out.pop();
return value;



Note that the additional private method flip is yet missing. However, I will state the envisioned complexity:



  • enqueue is $mathcal O(1)$ (amortized)

  • dequeue is $mathcal O(1)$ (amortized)

  • peek is $mathcal O(1)$ (amortized)

Intrigued? Great. So let's check flip:



void Queue::flip() 
while(not in.empty())
out.push(in.top());
in.pop();




flip takes all elements in in and moves them to out. It thereby changes the order of the elements, so that the top in in will be the last to get moved out of out. Note that we call flip only when out is empty.



Amortized analysis



*"Wait a second! That's $mathcal O(n)$" I hear you say. And that's completely correct. However, how often do we need to call flip? Or, rather more important, how often do elements get moved?



The answer on the latter question is: exactly one time from in to out. At no point will they move back. The number of flip calls is much trickier, though, but it doesn't really matter. At worst, flip may need to flip all elements, for example if we use it as follows:



for(int i = 0; i < 100; ++i) 
queue.enqueue(i);

for(int i = 0; i < 100; ++i)
queue.dequeue(); // first dequeue will flip



However, only the first dequeue will flip. All others will yield the element immediately. Therefore, if we enqueue $n$ elements and then dequeue all of them, we end up with dequeue()'s complexity as:



$$fracnmathcal O(1) + mathcal O(n)n = mathcal O(1).$$



We can compare that with your original variant:
$$fracnmathcal O(n)n = mathcal O(n)$$



This is why your code exceeded the time limit.



Further review on code



There are some other findings that don't need as much detail as the algorithm, but nonetheless can be improved:



  • there are some unused includes (<vector>)


  • using namespace std is considered bad practice

  • the names are misleading or at least not self-descriptive


  • peek() usually returns a value and does not print

  • the struct Queue should have been a class Queue due to the assumption that the elements are always in the right order.





share|improve this answer











$endgroup$






















    3












    $begingroup$

    You might want to look at the discussion tab for why the code is timing out. Basically the code should reverse the input stack only when peek or dequeue is called and not in enqueue.



    The rest of answer is a review of the code as posted and it ignores the fact that HackerRank supplied some of the code, such as the includes and the using namespace std. Issues such as readability and maintainability are beyond the scope of HackerRank but are considerations when writing good code.



    Avoid Using Namespace STD

    If you are coding professionally you probably should get out of the habit of using the "using namespace std;" statement. The code will more clearly define where cout and other functions are coming from (std::cin, std::cout). As you start using namespaces in your code it is better to identify where each function comes from because there may be function name collisions from different namespaces. The function cout you may override within your own classes. This stack overflow question discusses this in more detail.



    Magic Numbers

    Numeric constants in code are sometimes referred to as Magic Numbers, because there is no obvious meaning for them.
    The values for the variable k are defined by the problem, but it might be better to use symbolic constants rather than raw numbers in the switch statement. That would make the code easier to read and maintain. C++ provides a couple of methods for this, there could be an enum, or they could be defined as constants using const or constexpr. Any of these would make the code more readable. There is a discussion of this on stackoverflow.



    Use Descriptive Variable Names

    The variables s1 and s2 are not very clear, and if they weren't in a std::stack declarations I really would have no idea what they were. Since this is a queue problem it might be better to name them front and rear to represent what they are used for. It is very hard to maintain code with variable names such as s1, s2, q, t, k and x. As an example for k I might use queryIndex.



    Since the restrictions on all input indicates there will be no negative numbers it might be better to use unsigned rather than int.



    Prefer to Not Include What Isn't Necessary

    It is much better to only include what is necessary in a source file. There are currently 6 files included but only two are necessary (iostream and stack) for this implementation. Including cstdio is bad because it might lead the programmer to use C I/O statements rather the C++ ones. Including only what is needed improves compile times, because the contents of all the includes are part of the compilation. It could lead to other problems if you are implementing your own class rather than using a C++ container class (such as std::queue from #include <queue>).



    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <stack>


    Prefer One Declaration Per Line

    Maintaining code is easier when one can find the declarations for variables. It would be easier to find where s2 is declared if it was on a separate line.



     std::stack<int> s1, s2;


    Versus



     std::stack<int> s1;
    std::stack<int> s2;


    Remember you may win a lottery and may not be the one maintaining the code.



    The same reasoning applies to 2 statements on a line such as



     int k; cin>>k;





    share|improve this answer











    $endgroup$

















      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "196"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );






      KshitijV97 is a new contributor. Be nice, and check out our Code of Conduct.









      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225469%2fhackerrank-implement-queue-using-two-stacks-solution%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      5












      $begingroup$

      Algorithmic complexity for combined operations



      Containers are interesting elements in most programming languages: they have an internal state, namely their elements and therefore their size.



      This introduces an additional state compared to usual algorithmic asymptotical complexity analysis. For example, a naive implemented std::vector::push_back will yield $mathcal O(n^2)$ complexity if push_back increases the capacity only by one:



      // pseudo-code, also very bad performance and no error handling, do not use!
      void vector::push_back(T value)
      if(_size == _capacity)
      // has to move all elements and is therefore O(n)
      reserve(_capacity + 1);

      _data[_size++] = value;



      While trivial, this code has a severe problem: we have to copy all elements in ever iteration. If we use push_back in a loop, we end up with a quadratic complexity.



      The real push_back has therefore some tricks up in its sleeves, as the standard dictates that it will have $O(1)$ amortized complexity. More about that later in this review.



      However, this small introduction should give you a hint about the central flaw in your current approach.



      A hidden quadratic term




      I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$




      For this task, it's much more important to see the cost on both functions for $k$ enqueued elements, not a single one.



      So let's envision the queue 1,2,3,4. How many steps do we need?



      to enqueue 1: 
      1. put `1` in `s1`
      to enqueue 2:
      1. move `1` from `s1` to `s2`
      2. put `2` in `s1`
      3. move `1` from `s2` to `s1`
      - to enqueue 3:
      1. move `1` from `s1` to `s2`
      2. move `2` from `s1` to `s2`
      3. put `3` in `s1`
      4. move `2` from `s2` to `s1`
      5. move `1` from `s2` to `s1`
      - to enqueue 4:
      1. move `1` from `s1` to `s2`
      2. move `2` from `s1` to `s2`
      3. move `3` from `s1` to `s2`
      4. put `4` in `s1`
      5. move `3` from `s2` to `s1`
      6. move `2` from `s2` to `s1`
      7. move `1` from `s2` to `s1`


      We see that the $n$th element will take $2(n-1)$ swaps. Therefore, if we insert a total of $n$ elements into our queue, we end up with $mathcal O(n^2)$ to complete all enqueues.



      We need to do better.



      A better queue with two stacks



      So let's get back to the drawing board. What do we need?



      1. We need to enqueue

      2. We need to dequeue

      3. We need to peek.

      None of those terms indicates that we need to have all data in one stack. So first of all, we need to use better names, because s1 and s2 are pretty bland and non-descriptive:



      class Queue
      stack<int> in;
      stack<int> out;

      void flip(); // < new

      public:
      void enqueue(int);
      int dequeue();
      int peek();
      ;


      I'll implement the methods outside of the class declaration to keep the code segments short, but you're free to place them inline again. Note that I switched from a struct to a class, because its Queues job to make sure that in and out are handled correct; no one else should be able to change them.



      What will we use in and out for? Well, as long as we have elements in out, we will use them for dequeue and peek. And whatever gets enqueued gets pushed right ontop of in, no questions asked.



      The critical part is how to get an element from in to out, right? I let you think about that for some paragraphs, but you may also stop here and try it yourself; the declaration above contains a clue.



      So, let's have a look at my proposal for the definition of enqueue(), peek and dequeue():



      void Queue::enqueue(int value) 
      in.push(value);


      int Queue::peek()
      if (out.empty())
      flip();

      return out.top();


      int Queue::dequeue()
      if (out.empty())
      flip();

      int value = out.top();
      out.pop();
      return value;



      Note that the additional private method flip is yet missing. However, I will state the envisioned complexity:



      • enqueue is $mathcal O(1)$ (amortized)

      • dequeue is $mathcal O(1)$ (amortized)

      • peek is $mathcal O(1)$ (amortized)

      Intrigued? Great. So let's check flip:



      void Queue::flip() 
      while(not in.empty())
      out.push(in.top());
      in.pop();




      flip takes all elements in in and moves them to out. It thereby changes the order of the elements, so that the top in in will be the last to get moved out of out. Note that we call flip only when out is empty.



      Amortized analysis



      *"Wait a second! That's $mathcal O(n)$" I hear you say. And that's completely correct. However, how often do we need to call flip? Or, rather more important, how often do elements get moved?



      The answer on the latter question is: exactly one time from in to out. At no point will they move back. The number of flip calls is much trickier, though, but it doesn't really matter. At worst, flip may need to flip all elements, for example if we use it as follows:



      for(int i = 0; i < 100; ++i) 
      queue.enqueue(i);

      for(int i = 0; i < 100; ++i)
      queue.dequeue(); // first dequeue will flip



      However, only the first dequeue will flip. All others will yield the element immediately. Therefore, if we enqueue $n$ elements and then dequeue all of them, we end up with dequeue()'s complexity as:



      $$fracnmathcal O(1) + mathcal O(n)n = mathcal O(1).$$



      We can compare that with your original variant:
      $$fracnmathcal O(n)n = mathcal O(n)$$



      This is why your code exceeded the time limit.



      Further review on code



      There are some other findings that don't need as much detail as the algorithm, but nonetheless can be improved:



      • there are some unused includes (<vector>)


      • using namespace std is considered bad practice

      • the names are misleading or at least not self-descriptive


      • peek() usually returns a value and does not print

      • the struct Queue should have been a class Queue due to the assumption that the elements are always in the right order.





      share|improve this answer











      $endgroup$



















        5












        $begingroup$

        Algorithmic complexity for combined operations



        Containers are interesting elements in most programming languages: they have an internal state, namely their elements and therefore their size.



        This introduces an additional state compared to usual algorithmic asymptotical complexity analysis. For example, a naive implemented std::vector::push_back will yield $mathcal O(n^2)$ complexity if push_back increases the capacity only by one:



        // pseudo-code, also very bad performance and no error handling, do not use!
        void vector::push_back(T value)
        if(_size == _capacity)
        // has to move all elements and is therefore O(n)
        reserve(_capacity + 1);

        _data[_size++] = value;



        While trivial, this code has a severe problem: we have to copy all elements in ever iteration. If we use push_back in a loop, we end up with a quadratic complexity.



        The real push_back has therefore some tricks up in its sleeves, as the standard dictates that it will have $O(1)$ amortized complexity. More about that later in this review.



        However, this small introduction should give you a hint about the central flaw in your current approach.



        A hidden quadratic term




        I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$




        For this task, it's much more important to see the cost on both functions for $k$ enqueued elements, not a single one.



        So let's envision the queue 1,2,3,4. How many steps do we need?



        to enqueue 1: 
        1. put `1` in `s1`
        to enqueue 2:
        1. move `1` from `s1` to `s2`
        2. put `2` in `s1`
        3. move `1` from `s2` to `s1`
        - to enqueue 3:
        1. move `1` from `s1` to `s2`
        2. move `2` from `s1` to `s2`
        3. put `3` in `s1`
        4. move `2` from `s2` to `s1`
        5. move `1` from `s2` to `s1`
        - to enqueue 4:
        1. move `1` from `s1` to `s2`
        2. move `2` from `s1` to `s2`
        3. move `3` from `s1` to `s2`
        4. put `4` in `s1`
        5. move `3` from `s2` to `s1`
        6. move `2` from `s2` to `s1`
        7. move `1` from `s2` to `s1`


        We see that the $n$th element will take $2(n-1)$ swaps. Therefore, if we insert a total of $n$ elements into our queue, we end up with $mathcal O(n^2)$ to complete all enqueues.



        We need to do better.



        A better queue with two stacks



        So let's get back to the drawing board. What do we need?



        1. We need to enqueue

        2. We need to dequeue

        3. We need to peek.

        None of those terms indicates that we need to have all data in one stack. So first of all, we need to use better names, because s1 and s2 are pretty bland and non-descriptive:



        class Queue
        stack<int> in;
        stack<int> out;

        void flip(); // < new

        public:
        void enqueue(int);
        int dequeue();
        int peek();
        ;


        I'll implement the methods outside of the class declaration to keep the code segments short, but you're free to place them inline again. Note that I switched from a struct to a class, because its Queues job to make sure that in and out are handled correct; no one else should be able to change them.



        What will we use in and out for? Well, as long as we have elements in out, we will use them for dequeue and peek. And whatever gets enqueued gets pushed right ontop of in, no questions asked.



        The critical part is how to get an element from in to out, right? I let you think about that for some paragraphs, but you may also stop here and try it yourself; the declaration above contains a clue.



        So, let's have a look at my proposal for the definition of enqueue(), peek and dequeue():



        void Queue::enqueue(int value) 
        in.push(value);


        int Queue::peek()
        if (out.empty())
        flip();

        return out.top();


        int Queue::dequeue()
        if (out.empty())
        flip();

        int value = out.top();
        out.pop();
        return value;



        Note that the additional private method flip is yet missing. However, I will state the envisioned complexity:



        • enqueue is $mathcal O(1)$ (amortized)

        • dequeue is $mathcal O(1)$ (amortized)

        • peek is $mathcal O(1)$ (amortized)

        Intrigued? Great. So let's check flip:



        void Queue::flip() 
        while(not in.empty())
        out.push(in.top());
        in.pop();




        flip takes all elements in in and moves them to out. It thereby changes the order of the elements, so that the top in in will be the last to get moved out of out. Note that we call flip only when out is empty.



        Amortized analysis



        *"Wait a second! That's $mathcal O(n)$" I hear you say. And that's completely correct. However, how often do we need to call flip? Or, rather more important, how often do elements get moved?



        The answer on the latter question is: exactly one time from in to out. At no point will they move back. The number of flip calls is much trickier, though, but it doesn't really matter. At worst, flip may need to flip all elements, for example if we use it as follows:



        for(int i = 0; i < 100; ++i) 
        queue.enqueue(i);

        for(int i = 0; i < 100; ++i)
        queue.dequeue(); // first dequeue will flip



        However, only the first dequeue will flip. All others will yield the element immediately. Therefore, if we enqueue $n$ elements and then dequeue all of them, we end up with dequeue()'s complexity as:



        $$fracnmathcal O(1) + mathcal O(n)n = mathcal O(1).$$



        We can compare that with your original variant:
        $$fracnmathcal O(n)n = mathcal O(n)$$



        This is why your code exceeded the time limit.



        Further review on code



        There are some other findings that don't need as much detail as the algorithm, but nonetheless can be improved:



        • there are some unused includes (<vector>)


        • using namespace std is considered bad practice

        • the names are misleading or at least not self-descriptive


        • peek() usually returns a value and does not print

        • the struct Queue should have been a class Queue due to the assumption that the elements are always in the right order.





        share|improve this answer











        $endgroup$

















          5












          5








          5





          $begingroup$

          Algorithmic complexity for combined operations



          Containers are interesting elements in most programming languages: they have an internal state, namely their elements and therefore their size.



          This introduces an additional state compared to usual algorithmic asymptotical complexity analysis. For example, a naive implemented std::vector::push_back will yield $mathcal O(n^2)$ complexity if push_back increases the capacity only by one:



          // pseudo-code, also very bad performance and no error handling, do not use!
          void vector::push_back(T value)
          if(_size == _capacity)
          // has to move all elements and is therefore O(n)
          reserve(_capacity + 1);

          _data[_size++] = value;



          While trivial, this code has a severe problem: we have to copy all elements in ever iteration. If we use push_back in a loop, we end up with a quadratic complexity.



          The real push_back has therefore some tricks up in its sleeves, as the standard dictates that it will have $O(1)$ amortized complexity. More about that later in this review.



          However, this small introduction should give you a hint about the central flaw in your current approach.



          A hidden quadratic term




          I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$




          For this task, it's much more important to see the cost on both functions for $k$ enqueued elements, not a single one.



          So let's envision the queue 1,2,3,4. How many steps do we need?



          to enqueue 1: 
          1. put `1` in `s1`
          to enqueue 2:
          1. move `1` from `s1` to `s2`
          2. put `2` in `s1`
          3. move `1` from `s2` to `s1`
          - to enqueue 3:
          1. move `1` from `s1` to `s2`
          2. move `2` from `s1` to `s2`
          3. put `3` in `s1`
          4. move `2` from `s2` to `s1`
          5. move `1` from `s2` to `s1`
          - to enqueue 4:
          1. move `1` from `s1` to `s2`
          2. move `2` from `s1` to `s2`
          3. move `3` from `s1` to `s2`
          4. put `4` in `s1`
          5. move `3` from `s2` to `s1`
          6. move `2` from `s2` to `s1`
          7. move `1` from `s2` to `s1`


          We see that the $n$th element will take $2(n-1)$ swaps. Therefore, if we insert a total of $n$ elements into our queue, we end up with $mathcal O(n^2)$ to complete all enqueues.



          We need to do better.



          A better queue with two stacks



          So let's get back to the drawing board. What do we need?



          1. We need to enqueue

          2. We need to dequeue

          3. We need to peek.

          None of those terms indicates that we need to have all data in one stack. So first of all, we need to use better names, because s1 and s2 are pretty bland and non-descriptive:



          class Queue
          stack<int> in;
          stack<int> out;

          void flip(); // < new

          public:
          void enqueue(int);
          int dequeue();
          int peek();
          ;


          I'll implement the methods outside of the class declaration to keep the code segments short, but you're free to place them inline again. Note that I switched from a struct to a class, because its Queues job to make sure that in and out are handled correct; no one else should be able to change them.



          What will we use in and out for? Well, as long as we have elements in out, we will use them for dequeue and peek. And whatever gets enqueued gets pushed right ontop of in, no questions asked.



          The critical part is how to get an element from in to out, right? I let you think about that for some paragraphs, but you may also stop here and try it yourself; the declaration above contains a clue.



          So, let's have a look at my proposal for the definition of enqueue(), peek and dequeue():



          void Queue::enqueue(int value) 
          in.push(value);


          int Queue::peek()
          if (out.empty())
          flip();

          return out.top();


          int Queue::dequeue()
          if (out.empty())
          flip();

          int value = out.top();
          out.pop();
          return value;



          Note that the additional private method flip is yet missing. However, I will state the envisioned complexity:



          • enqueue is $mathcal O(1)$ (amortized)

          • dequeue is $mathcal O(1)$ (amortized)

          • peek is $mathcal O(1)$ (amortized)

          Intrigued? Great. So let's check flip:



          void Queue::flip() 
          while(not in.empty())
          out.push(in.top());
          in.pop();




          flip takes all elements in in and moves them to out. It thereby changes the order of the elements, so that the top in in will be the last to get moved out of out. Note that we call flip only when out is empty.



          Amortized analysis



          *"Wait a second! That's $mathcal O(n)$" I hear you say. And that's completely correct. However, how often do we need to call flip? Or, rather more important, how often do elements get moved?



          The answer on the latter question is: exactly one time from in to out. At no point will they move back. The number of flip calls is much trickier, though, but it doesn't really matter. At worst, flip may need to flip all elements, for example if we use it as follows:



          for(int i = 0; i < 100; ++i) 
          queue.enqueue(i);

          for(int i = 0; i < 100; ++i)
          queue.dequeue(); // first dequeue will flip



          However, only the first dequeue will flip. All others will yield the element immediately. Therefore, if we enqueue $n$ elements and then dequeue all of them, we end up with dequeue()'s complexity as:



          $$fracnmathcal O(1) + mathcal O(n)n = mathcal O(1).$$



          We can compare that with your original variant:
          $$fracnmathcal O(n)n = mathcal O(n)$$



          This is why your code exceeded the time limit.



          Further review on code



          There are some other findings that don't need as much detail as the algorithm, but nonetheless can be improved:



          • there are some unused includes (<vector>)


          • using namespace std is considered bad practice

          • the names are misleading or at least not self-descriptive


          • peek() usually returns a value and does not print

          • the struct Queue should have been a class Queue due to the assumption that the elements are always in the right order.





          share|improve this answer











          $endgroup$



          Algorithmic complexity for combined operations



          Containers are interesting elements in most programming languages: they have an internal state, namely their elements and therefore their size.



          This introduces an additional state compared to usual algorithmic asymptotical complexity analysis. For example, a naive implemented std::vector::push_back will yield $mathcal O(n^2)$ complexity if push_back increases the capacity only by one:



          // pseudo-code, also very bad performance and no error handling, do not use!
          void vector::push_back(T value)
          if(_size == _capacity)
          // has to move all elements and is therefore O(n)
          reserve(_capacity + 1);

          _data[_size++] = value;



          While trivial, this code has a severe problem: we have to copy all elements in ever iteration. If we use push_back in a loop, we end up with a quadratic complexity.



          The real push_back has therefore some tricks up in its sleeves, as the standard dictates that it will have $O(1)$ amortized complexity. More about that later in this review.



          However, this small introduction should give you a hint about the central flaw in your current approach.



          A hidden quadratic term




          I implemented dequeue() in $O(1)$ at the cost of enqueue() in $O(n)$




          For this task, it's much more important to see the cost on both functions for $k$ enqueued elements, not a single one.



          So let's envision the queue 1,2,3,4. How many steps do we need?



          to enqueue 1: 
          1. put `1` in `s1`
          to enqueue 2:
          1. move `1` from `s1` to `s2`
          2. put `2` in `s1`
          3. move `1` from `s2` to `s1`
          - to enqueue 3:
          1. move `1` from `s1` to `s2`
          2. move `2` from `s1` to `s2`
          3. put `3` in `s1`
          4. move `2` from `s2` to `s1`
          5. move `1` from `s2` to `s1`
          - to enqueue 4:
          1. move `1` from `s1` to `s2`
          2. move `2` from `s1` to `s2`
          3. move `3` from `s1` to `s2`
          4. put `4` in `s1`
          5. move `3` from `s2` to `s1`
          6. move `2` from `s2` to `s1`
          7. move `1` from `s2` to `s1`


          We see that the $n$th element will take $2(n-1)$ swaps. Therefore, if we insert a total of $n$ elements into our queue, we end up with $mathcal O(n^2)$ to complete all enqueues.



          We need to do better.



          A better queue with two stacks



          So let's get back to the drawing board. What do we need?



          1. We need to enqueue

          2. We need to dequeue

          3. We need to peek.

          None of those terms indicates that we need to have all data in one stack. So first of all, we need to use better names, because s1 and s2 are pretty bland and non-descriptive:



          class Queue
          stack<int> in;
          stack<int> out;

          void flip(); // < new

          public:
          void enqueue(int);
          int dequeue();
          int peek();
          ;


          I'll implement the methods outside of the class declaration to keep the code segments short, but you're free to place them inline again. Note that I switched from a struct to a class, because its Queues job to make sure that in and out are handled correct; no one else should be able to change them.



          What will we use in and out for? Well, as long as we have elements in out, we will use them for dequeue and peek. And whatever gets enqueued gets pushed right ontop of in, no questions asked.



          The critical part is how to get an element from in to out, right? I let you think about that for some paragraphs, but you may also stop here and try it yourself; the declaration above contains a clue.



          So, let's have a look at my proposal for the definition of enqueue(), peek and dequeue():



          void Queue::enqueue(int value) 
          in.push(value);


          int Queue::peek()
          if (out.empty())
          flip();

          return out.top();


          int Queue::dequeue()
          if (out.empty())
          flip();

          int value = out.top();
          out.pop();
          return value;



          Note that the additional private method flip is yet missing. However, I will state the envisioned complexity:



          • enqueue is $mathcal O(1)$ (amortized)

          • dequeue is $mathcal O(1)$ (amortized)

          • peek is $mathcal O(1)$ (amortized)

          Intrigued? Great. So let's check flip:



          void Queue::flip() 
          while(not in.empty())
          out.push(in.top());
          in.pop();




          flip takes all elements in in and moves them to out. It thereby changes the order of the elements, so that the top in in will be the last to get moved out of out. Note that we call flip only when out is empty.



          Amortized analysis



          *"Wait a second! That's $mathcal O(n)$" I hear you say. And that's completely correct. However, how often do we need to call flip? Or, rather more important, how often do elements get moved?



          The answer on the latter question is: exactly one time from in to out. At no point will they move back. The number of flip calls is much trickier, though, but it doesn't really matter. At worst, flip may need to flip all elements, for example if we use it as follows:



          for(int i = 0; i < 100; ++i) 
          queue.enqueue(i);

          for(int i = 0; i < 100; ++i)
          queue.dequeue(); // first dequeue will flip



          However, only the first dequeue will flip. All others will yield the element immediately. Therefore, if we enqueue $n$ elements and then dequeue all of them, we end up with dequeue()'s complexity as:



          $$fracnmathcal O(1) + mathcal O(n)n = mathcal O(1).$$



          We can compare that with your original variant:
          $$fracnmathcal O(n)n = mathcal O(n)$$



          This is why your code exceeded the time limit.



          Further review on code



          There are some other findings that don't need as much detail as the algorithm, but nonetheless can be improved:



          • there are some unused includes (<vector>)


          • using namespace std is considered bad practice

          • the names are misleading or at least not self-descriptive


          • peek() usually returns a value and does not print

          • the struct Queue should have been a class Queue due to the assumption that the elements are always in the right order.






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 hours ago









          dfhwze

          7,3491 gold badge18 silver badges46 bronze badges




          7,3491 gold badge18 silver badges46 bronze badges










          answered 3 hours ago









          ZetaZeta

          15.8k2 gold badges39 silver badges75 bronze badges




          15.8k2 gold badges39 silver badges75 bronze badges


























              3












              $begingroup$

              You might want to look at the discussion tab for why the code is timing out. Basically the code should reverse the input stack only when peek or dequeue is called and not in enqueue.



              The rest of answer is a review of the code as posted and it ignores the fact that HackerRank supplied some of the code, such as the includes and the using namespace std. Issues such as readability and maintainability are beyond the scope of HackerRank but are considerations when writing good code.



              Avoid Using Namespace STD

              If you are coding professionally you probably should get out of the habit of using the "using namespace std;" statement. The code will more clearly define where cout and other functions are coming from (std::cin, std::cout). As you start using namespaces in your code it is better to identify where each function comes from because there may be function name collisions from different namespaces. The function cout you may override within your own classes. This stack overflow question discusses this in more detail.



              Magic Numbers

              Numeric constants in code are sometimes referred to as Magic Numbers, because there is no obvious meaning for them.
              The values for the variable k are defined by the problem, but it might be better to use symbolic constants rather than raw numbers in the switch statement. That would make the code easier to read and maintain. C++ provides a couple of methods for this, there could be an enum, or they could be defined as constants using const or constexpr. Any of these would make the code more readable. There is a discussion of this on stackoverflow.



              Use Descriptive Variable Names

              The variables s1 and s2 are not very clear, and if they weren't in a std::stack declarations I really would have no idea what they were. Since this is a queue problem it might be better to name them front and rear to represent what they are used for. It is very hard to maintain code with variable names such as s1, s2, q, t, k and x. As an example for k I might use queryIndex.



              Since the restrictions on all input indicates there will be no negative numbers it might be better to use unsigned rather than int.



              Prefer to Not Include What Isn't Necessary

              It is much better to only include what is necessary in a source file. There are currently 6 files included but only two are necessary (iostream and stack) for this implementation. Including cstdio is bad because it might lead the programmer to use C I/O statements rather the C++ ones. Including only what is needed improves compile times, because the contents of all the includes are part of the compilation. It could lead to other problems if you are implementing your own class rather than using a C++ container class (such as std::queue from #include <queue>).



              #include <cmath>
              #include <cstdio>
              #include <vector>
              #include <iostream>
              #include <algorithm>
              #include <stack>


              Prefer One Declaration Per Line

              Maintaining code is easier when one can find the declarations for variables. It would be easier to find where s2 is declared if it was on a separate line.



               std::stack<int> s1, s2;


              Versus



               std::stack<int> s1;
              std::stack<int> s2;


              Remember you may win a lottery and may not be the one maintaining the code.



              The same reasoning applies to 2 statements on a line such as



               int k; cin>>k;





              share|improve this answer











              $endgroup$



















                3












                $begingroup$

                You might want to look at the discussion tab for why the code is timing out. Basically the code should reverse the input stack only when peek or dequeue is called and not in enqueue.



                The rest of answer is a review of the code as posted and it ignores the fact that HackerRank supplied some of the code, such as the includes and the using namespace std. Issues such as readability and maintainability are beyond the scope of HackerRank but are considerations when writing good code.



                Avoid Using Namespace STD

                If you are coding professionally you probably should get out of the habit of using the "using namespace std;" statement. The code will more clearly define where cout and other functions are coming from (std::cin, std::cout). As you start using namespaces in your code it is better to identify where each function comes from because there may be function name collisions from different namespaces. The function cout you may override within your own classes. This stack overflow question discusses this in more detail.



                Magic Numbers

                Numeric constants in code are sometimes referred to as Magic Numbers, because there is no obvious meaning for them.
                The values for the variable k are defined by the problem, but it might be better to use symbolic constants rather than raw numbers in the switch statement. That would make the code easier to read and maintain. C++ provides a couple of methods for this, there could be an enum, or they could be defined as constants using const or constexpr. Any of these would make the code more readable. There is a discussion of this on stackoverflow.



                Use Descriptive Variable Names

                The variables s1 and s2 are not very clear, and if they weren't in a std::stack declarations I really would have no idea what they were. Since this is a queue problem it might be better to name them front and rear to represent what they are used for. It is very hard to maintain code with variable names such as s1, s2, q, t, k and x. As an example for k I might use queryIndex.



                Since the restrictions on all input indicates there will be no negative numbers it might be better to use unsigned rather than int.



                Prefer to Not Include What Isn't Necessary

                It is much better to only include what is necessary in a source file. There are currently 6 files included but only two are necessary (iostream and stack) for this implementation. Including cstdio is bad because it might lead the programmer to use C I/O statements rather the C++ ones. Including only what is needed improves compile times, because the contents of all the includes are part of the compilation. It could lead to other problems if you are implementing your own class rather than using a C++ container class (such as std::queue from #include <queue>).



                #include <cmath>
                #include <cstdio>
                #include <vector>
                #include <iostream>
                #include <algorithm>
                #include <stack>


                Prefer One Declaration Per Line

                Maintaining code is easier when one can find the declarations for variables. It would be easier to find where s2 is declared if it was on a separate line.



                 std::stack<int> s1, s2;


                Versus



                 std::stack<int> s1;
                std::stack<int> s2;


                Remember you may win a lottery and may not be the one maintaining the code.



                The same reasoning applies to 2 statements on a line such as



                 int k; cin>>k;





                share|improve this answer











                $endgroup$

















                  3












                  3








                  3





                  $begingroup$

                  You might want to look at the discussion tab for why the code is timing out. Basically the code should reverse the input stack only when peek or dequeue is called and not in enqueue.



                  The rest of answer is a review of the code as posted and it ignores the fact that HackerRank supplied some of the code, such as the includes and the using namespace std. Issues such as readability and maintainability are beyond the scope of HackerRank but are considerations when writing good code.



                  Avoid Using Namespace STD

                  If you are coding professionally you probably should get out of the habit of using the "using namespace std;" statement. The code will more clearly define where cout and other functions are coming from (std::cin, std::cout). As you start using namespaces in your code it is better to identify where each function comes from because there may be function name collisions from different namespaces. The function cout you may override within your own classes. This stack overflow question discusses this in more detail.



                  Magic Numbers

                  Numeric constants in code are sometimes referred to as Magic Numbers, because there is no obvious meaning for them.
                  The values for the variable k are defined by the problem, but it might be better to use symbolic constants rather than raw numbers in the switch statement. That would make the code easier to read and maintain. C++ provides a couple of methods for this, there could be an enum, or they could be defined as constants using const or constexpr. Any of these would make the code more readable. There is a discussion of this on stackoverflow.



                  Use Descriptive Variable Names

                  The variables s1 and s2 are not very clear, and if they weren't in a std::stack declarations I really would have no idea what they were. Since this is a queue problem it might be better to name them front and rear to represent what they are used for. It is very hard to maintain code with variable names such as s1, s2, q, t, k and x. As an example for k I might use queryIndex.



                  Since the restrictions on all input indicates there will be no negative numbers it might be better to use unsigned rather than int.



                  Prefer to Not Include What Isn't Necessary

                  It is much better to only include what is necessary in a source file. There are currently 6 files included but only two are necessary (iostream and stack) for this implementation. Including cstdio is bad because it might lead the programmer to use C I/O statements rather the C++ ones. Including only what is needed improves compile times, because the contents of all the includes are part of the compilation. It could lead to other problems if you are implementing your own class rather than using a C++ container class (such as std::queue from #include <queue>).



                  #include <cmath>
                  #include <cstdio>
                  #include <vector>
                  #include <iostream>
                  #include <algorithm>
                  #include <stack>


                  Prefer One Declaration Per Line

                  Maintaining code is easier when one can find the declarations for variables. It would be easier to find where s2 is declared if it was on a separate line.



                   std::stack<int> s1, s2;


                  Versus



                   std::stack<int> s1;
                  std::stack<int> s2;


                  Remember you may win a lottery and may not be the one maintaining the code.



                  The same reasoning applies to 2 statements on a line such as



                   int k; cin>>k;





                  share|improve this answer











                  $endgroup$



                  You might want to look at the discussion tab for why the code is timing out. Basically the code should reverse the input stack only when peek or dequeue is called and not in enqueue.



                  The rest of answer is a review of the code as posted and it ignores the fact that HackerRank supplied some of the code, such as the includes and the using namespace std. Issues such as readability and maintainability are beyond the scope of HackerRank but are considerations when writing good code.



                  Avoid Using Namespace STD

                  If you are coding professionally you probably should get out of the habit of using the "using namespace std;" statement. The code will more clearly define where cout and other functions are coming from (std::cin, std::cout). As you start using namespaces in your code it is better to identify where each function comes from because there may be function name collisions from different namespaces. The function cout you may override within your own classes. This stack overflow question discusses this in more detail.



                  Magic Numbers

                  Numeric constants in code are sometimes referred to as Magic Numbers, because there is no obvious meaning for them.
                  The values for the variable k are defined by the problem, but it might be better to use symbolic constants rather than raw numbers in the switch statement. That would make the code easier to read and maintain. C++ provides a couple of methods for this, there could be an enum, or they could be defined as constants using const or constexpr. Any of these would make the code more readable. There is a discussion of this on stackoverflow.



                  Use Descriptive Variable Names

                  The variables s1 and s2 are not very clear, and if they weren't in a std::stack declarations I really would have no idea what they were. Since this is a queue problem it might be better to name them front and rear to represent what they are used for. It is very hard to maintain code with variable names such as s1, s2, q, t, k and x. As an example for k I might use queryIndex.



                  Since the restrictions on all input indicates there will be no negative numbers it might be better to use unsigned rather than int.



                  Prefer to Not Include What Isn't Necessary

                  It is much better to only include what is necessary in a source file. There are currently 6 files included but only two are necessary (iostream and stack) for this implementation. Including cstdio is bad because it might lead the programmer to use C I/O statements rather the C++ ones. Including only what is needed improves compile times, because the contents of all the includes are part of the compilation. It could lead to other problems if you are implementing your own class rather than using a C++ container class (such as std::queue from #include <queue>).



                  #include <cmath>
                  #include <cstdio>
                  #include <vector>
                  #include <iostream>
                  #include <algorithm>
                  #include <stack>


                  Prefer One Declaration Per Line

                  Maintaining code is easier when one can find the declarations for variables. It would be easier to find where s2 is declared if it was on a separate line.



                   std::stack<int> s1, s2;


                  Versus



                   std::stack<int> s1;
                  std::stack<int> s2;


                  Remember you may win a lottery and may not be the one maintaining the code.



                  The same reasoning applies to 2 statements on a line such as



                   int k; cin>>k;






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 3 hours ago









                  dfhwze

                  7,3491 gold badge18 silver badges46 bronze badges




                  7,3491 gold badge18 silver badges46 bronze badges










                  answered 3 hours ago









                  pacmaninbwpacmaninbw

                  7,0192 gold badges19 silver badges44 bronze badges




                  7,0192 gold badges19 silver badges44 bronze badges























                      KshitijV97 is a new contributor. Be nice, and check out our Code of Conduct.









                      draft saved

                      draft discarded


















                      KshitijV97 is a new contributor. Be nice, and check out our Code of Conduct.












                      KshitijV97 is a new contributor. Be nice, and check out our Code of Conduct.











                      KshitijV97 is a new contributor. Be nice, and check out our Code of Conduct.














                      Thanks for contributing an answer to Code Review Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      Use MathJax to format equations. MathJax reference.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f225469%2fhackerrank-implement-queue-using-two-stacks-solution%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                      Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                      François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480