スタックの順列

スタックの順列
GfG Practice で試してみる

空のスタックがあり、プッシュおよびポップ操作を実行できます。 2 つの配列が与えられています [] そして b[] ここで、a[] は要素がスタックにプッシュされる順序を表し、b[] は要素がスタックからポップされる順序を表します。指定されたプッシュ シーケンスとポップ シーケンスが有効かどうかを確認します。

例:  

入力: a[] = [1 2 3] b[] = [2 1 3]
出力: 真実
説明:   1 と 2 を押します。 b[] には 2 が必要なので、最初に 2 をポップし、次に 1 をポップします。最後に3を押してポップします。プッシュおよびポップのシーケンスは、a[] および b[] と一致します。

入力: a[] = [1 2 3] b[] = [3 1 2]
出力: 間違い
説明: 1、2、3 を押した後、必要に応じて 3 をポップできます。しかし、b[] の次の要素は 1 ですが、スタックのトップは 2 です。1 は 2 の下でブロックされているため、この順序は達成できません。

目次

[単純なアプローチ] キューの使用 - O(n) 時間と O(n) スペース

アイデアは、次を使用して処理する残りの要素を追跡しながら、スタック操作をシミュレートすることです。

a[] から要素を順番にプッシュし、要素ごとに b[] の前(予想されるポップ順序)と一致するかどうかを確認します。一致する場合は、b[] から削除します。そうでない場合は、それをスタックにプッシュします。各プッシュの後、スタックの先頭が b[] の先頭と一致するかどうかもチェックし、スタックからポップして b[] から削除します。これを繰り返すことで、b[] 内のすべての要素が一致するかどうかを確認します。 「はい」の場合、ポップ シーケンスは有効です。それ以外の場合はそうではありません。

C++
   #include          #include         #include         #include         using     namespace     std  ;   bool     checkPerm  (  vector   <  int  >&     a       vector   <  int  >&     b  )     {      queue   <  int  >     q1  ;      for     (  int     i     =     0  ;     i      <     a  .  size  ();     i  ++  )         q1  .  push  (  a  [  i  ]);      queue   <  int  >     q2  ;      for     (  int     i     =     0  ;     i      <     b  .  size  ();     i  ++  )      q2  .  push  (  b  [  i  ]);      stack   <  int  >     st  ;          // Dequeue all items one by one      while     (  !  q1  .  empty  ())     {      int     ele     =     q1  .  front  ();      q1  .  pop  ();          if     (  ele     ==     q2  .  front  ())     {          // If matches dequeue from output queue      q2  .  pop  ();          // Pop from stack while top matches q2 front      while     (  !  st  .  empty  ()     &&     !  q2  .  empty  ()     &&     st  .  top  ()     ==     q2  .  front  ())     {      st  .  pop  ();      q2  .  pop  ();      }      }      else     {      st  .  push  (  ele  );      }      }          return     q2  .  empty  ();   }   int     main  ()     {      vector   <  int  >     a     =     {  1       2       3  };      vector   <  int  >     b     =     {  3       2       1  };          if     (  checkPerm  (  a       b  ))      cout      < <     'true'      < <     endl  ;      else      cout      < <     'false'      < <     endl  ;      return     0  ;   }   
Java
   import     java.util.LinkedList  ;   import     java.util.Queue  ;   import     java.util.Stack  ;   public     class   GfG     {      static     boolean     checkPerm  (  int  []     a       int  []     b  )     {      Queue   <  Integer  >     q1     =     new     LinkedList   <>  ();      for     (  int     i     =     0  ;     i      <     a  .  length  ;     i  ++  )         q1  .  add  (  a  [  i  ]  );      Queue   <  Integer  >     q2     =     new     LinkedList   <>  ();      for     (  int     i     =     0  ;     i      <     b  .  length  ;     i  ++  )      q2  .  add  (  b  [  i  ]  );      Stack   <  Integer  >     st     =     new     Stack   <>  ();          // Dequeue all items one by one      while     (  !  q1  .  isEmpty  ())     {      int     ele     =     q1  .  poll  ();          if     (  ele     ==     q2  .  peek  ())     {          // If matches dequeue from output queue      q2  .  poll  ();          // Pop from stack while top matches q2 front      while     (  !  st  .  isEmpty  ()     &&     !  q2  .  isEmpty  ()     &&     st  .  peek  ()     ==     q2  .  peek  ())     {      st  .  pop  ();      q2  .  poll  ();      }      }      else     {      st  .  push  (  ele  );      }      }          return     q2  .  isEmpty  ();      }      public     static     void     main  (  String  []     args  )     {      int  []     a     =     {  1       2       3  };      int  []     b     =     {  3       2       1  };          if     (  checkPerm  (  a       b  ))      System  .  out  .  println  (  'true'  );      else      System  .  out  .  println  (  'false'  );      }   }   
Python
   from   collections   import   deque   def   checkPerm  (  a     b  ):   q1   =   deque  (  a  )   q2   =   deque  (  b  )   st   =   []   # Dequeue all items one by one   while   q1  :   ele   =   q1  .  popleft  ()   if   ele   ==   q2  [  0  ]:   # If matches dequeue from output queue   q2  .  popleft  ()   # Pop from stack while top matches q2 front   while   st   and   q2   and   st  [  -  1  ]   ==   q2  [  0  ]:   st  .  pop  ()   q2  .  popleft  ()   else  :   st  .  append  (  ele  )   return   not   q2   if   __name__   ==   '__main__'  :   a   =   [  1     2     3  ]   b   =   [  3     2     1  ]   if   checkPerm  (  a     b  ):   print  (  'true'  )   else  :   print  (  'false'  )   
C#
   using     System  ;   using     System.Collections.Generic  ;   public     class     GfG     {      static     bool     checkPerm  (  int  []     a       int  []     b  )     {      Queue   <  int  >     q1     =     new     Queue   <  int  >  (  a  );      Queue   <  int  >     q2     =     new     Queue   <  int  >  (  b  );      Stack   <  int  >     st     =     new     Stack   <  int  >  ();          // Dequeue all items one by one      while     (  q1  .  Count     >     0  )     {      int     ele     =     q1  .  Dequeue  ();          if     (  ele     ==     q2  .  Peek  ())     {          // If matches dequeue from output queue      q2  .  Dequeue  ();          // Pop from stack while top matches q2 front      while     (  st  .  Count     >     0     &&     q2  .  Count     >     0     &&     st  .  Peek  ()     ==     q2  .  Peek  ())      {      st  .  Pop  ();      q2  .  Dequeue  ();      }      }      else      {      st  .  Push  (  ele  );      }      }          return     q2  .  Count     ==     0  ;      }      public     static     void     Main  ()     {      int  []     a     =     {     1       2       3     };      int  []     b     =     {     3       2       1     };          if     (  checkPerm  (  a       b  ))      Console  .  WriteLine  (  'true'  );      else      Console  .  WriteLine  (  'false'  );      }   }   
JavaScript
   function     checkPerm  (  a       b  )     {          // simulate queue with array      let     q1     =     a  ;             // simulate queue with array      let     q2     =     b  ;         let     st     =     [];      // pointer for front of q1      let     front1     =     0  ;             // pointer for front of q2      let     front2     =     0  ;             while     (  front1      <     q1  .  length  )     {      let     ele     =     q1  [  front1  ];      front1  ++  ;      if     (  ele     ===     q2  [  front2  ])     {      front2  ++  ;      // Pop from stack while top matches q2 front      while     (  st  .  length     >     0     &&     st  [  st  .  length     -     1  ]     ===     q2  [  front2  ])     {      st  .  pop  ();      front2  ++  ;      }      }     else     {      st  .  push  (  ele  );      }      }      return     front2     ===     q2  .  length  ;   }   // Driver Code   let     a     =     [  1       2       3  ];   let     b     =     [  3       2       1  ];   console  .  log  (  checkPerm  (  a       b  ));      

出力
true  

[想定されるアプローチ] プッシュとポップのシミュレーション - O(n) 時間と O(n) 空間

このアプローチでは、実際にはキューを構築したり、入力配列を変更したりしません。代わりに、スタック上でプッシュおよびポップ操作を直接シミュレートします。

a[] の各要素は 1 つずつスタックにプッシュされます。プッシュするたびに、スタックの最上位が b[] の現在の要素と一致するかどうかを確認します。存在する場合は、それをスタックからポップし、b[] 内で前に進みます。このプロセスは、a[] のすべての要素がプッシュされてチェックされるまで繰り返されます。最後までに b[] のすべての要素が正常に一致してポップされた場合、置換は有効です (true を返します)。それ以外の場合は無効です (false を返します)。

C++
   #include          #include         #include         using     namespace     std  ;   bool     checkPerm  (  vector   <  int  >&     a       vector   <  int  >&     b  )     {      stack   <  int  >     st  ;      int     j     =     0  ;      for     (  int     i     =     0  ;     i      <     a  .  size  ();     i  ++  )     {          // Push top of a[] to stack      st  .  push  (  a  [  i  ]);      // Keep popping from stack while it      // matches front of the output queue      while     (  !  st  .  empty  ()     &&     st  .  top  ()     ==     b  [  j  ])     {      st  .  pop  ();      j  ++  ;      }      }      return     (  j     ==     b  .  size  ());   }   int     main  ()     {      vector   <  int  >     a     =     {  1       2       3  };      vector   <  int  >     b     =     {  2       1       3  };      cout      < <     (  checkPerm  (  a       b  )     ?     'true'     :     'false'  )      < <     endl  ;      return     0  ;   }   
Java
   import     java.util.Stack  ;   public     class   GfG     {      static     boolean     checkPerm  (  int  []     a       int  []     b  )     {      Stack   <  Integer  >     st     =     new     Stack   <>  ();      int     j     =     0  ;      for     (  int     i     =     0  ;     i      <     a  .  length  ;     i  ++  )     {          // Push top of a[] to stack      st  .  push  (  a  [  i  ]  );      // Keep popping from stack while it      // matches front of the output array      while     (  !  st  .  isEmpty  ()     &&     st  .  peek  ().  equals  (  b  [  j  ]  ))     {      st  .  pop  ();      j  ++  ;      }      }      return     (  j     ==     b  .  length  );      }      public     static     void     main  (  String  []     args  )     {      int  []     a     =     {  1       2       3  };      int  []     b     =     {  2       1       3  };      System  .  out  .  println  (  checkPerm  (  a       b  )     ?     'true'     :     'false'  );      }   }   
Python
   def   checkPerm  (  a     b  ):   st   =   []   j   =   0   for   i   in   range  (  len  (  a  )):   # Push top of a[] to stack   st  .  append  (  a  [  i  ])   # Keep popping from stack while it   # matches front of the output queue   while   st   and   st  [  -  1  ]   ==   b  [  j  ]:   st  .  pop  ()   j   +=   1   return   j   ==   len  (  b  )   if   __name__   ==   '__main__'  :   a   =   [  1     2     3  ]   b   =   [  2     1     3  ]   print  (  'true'   if   checkPerm  (  a     b  )   else   'false'  )   
C#
   using     System  ;   using     System.Collections.Generic  ;   class     GfG     {      static     bool     checkPerm  (  int  []     a       int  []     b  )     {      Stack   <  int  >     stack     =     new     Stack   <  int  >  ();      int     j     =     0  ;      for     (  int     i     =     0  ;     i      <     a  .  Length  ;     i  ++  )     {      // Push top of a[] to stack      stack  .  Push  (  a  [  i  ]);      // Keep popping from stack while it matches b[j]      while     (  stack  .  Count     >     0     &&     stack  .  Peek  ()     ==     b  [  j  ])     {      stack  .  Pop  ();      j  ++  ;      }      }      return     j     ==     b  .  Length  ;      }      static     void     Main  ()     {      int  []     a     =     {     1       2       3     };      int  []     b     =     {     2       1       3     };      Console  .  WriteLine  (  checkPerm  (  a       b  )     ?     'true'     :     'false'  );      }   }   
JavaScript
   function     checkPerm  (  a       b  )     {      const     stack     =     [];      let     j     =     0  ;      for     (  let     i     =     0  ;     i      <     a  .  length  ;     i  ++  )     {          // Push top of a[] to stack      stack  .  push  (  a  [  i  ]);      // Keep popping from stack while it      // matches front of the output queue      while     (  stack  .  length     >     0     &&     stack  [  stack  .  length     -     1  ]     ===     b  [  j  ])     {      stack  .  pop  ();      j  ++  ;      }      }      return     j     ===     b  .  length  ;   }   //Driven Code   const     a     =     [  1       2       3  ];   const     b     =     [  2       1       3  ];   console  .  log  (  checkPerm  (  a       b  )     ?     'true'     :     'false'  );   

出力
true  
クイズの作成