Sprawdź, czy lista połączona z pętlą jest palindromem, czy nie

Sprawdź, czy lista połączona z pętlą jest palindromem, czy nie

Biorąc pod uwagę połączoną listę z pętlą, zadaniem jest sprawdzenie, czy jest to palindrom, czy nie. Nie możesz usunąć pętli.  

Sprawdź, czy lista połączona z pętlą jest palindromem, czy nie

Przykłady:   

Input : 1 -> 2 -> 3 -> 2 /| |/ ------- 1 Output: Palindrome Linked list is 1 2 3 2 1 which is a palindrome. Input : 1 -> 2 -> 3 -> 4 /| |/ ------- 1 Output: Not Palindrome Linked list is 1 2 3 4 1 which is a not palindrome.  

Algorytm:

  1. Wykryj pętlę za pomocą algorytmu wykrywania cyklu Floyda.
  2. Następnie znajdź węzeł początkowy pętli, jak opisano w Ten
  3. Sprawdź, czy połączona lista jest palindromowa, czy nie, jak omówiono w Ten

Poniżej realizacja. 

C++
   // C++ program to check if a linked list with   // loop is palindrome or not.   #include       using     namespace     std  ;   /* Link list node */   struct     Node   {      int     data  ;      struct     Node     *     next  ;   };   /* Function to find loop starting node.   loop_node --> Pointer to one of the loop nodes   head --> Pointer to the start node of the linked list */   Node  *     getLoopstart  (  Node     *  loop_node       Node     *  head  )   {      Node     *  ptr1     =     loop_node  ;      Node     *  ptr2     =     loop_node  ;      // Count the number of nodes in loop      unsigned     int     k     =     1       i  ;      while     (  ptr1  ->  next     !=     ptr2  )      {      ptr1     =     ptr1  ->  next  ;      k  ++  ;      }      // Fix one pointer to head      ptr1     =     head  ;      // And the other pointer to k nodes after head      ptr2     =     head  ;      for     (  i     =     0  ;     i      <     k  ;     i  ++  )      ptr2     =     ptr2  ->  next  ;      /* Move both pointers at the same pace    they will meet at loop starting node */      while     (  ptr2     !=     ptr1  )      {      ptr1     =     ptr1  ->  next  ;      ptr2     =     ptr2  ->  next  ;      }      return     ptr1  ;   }   /* This function detects and find loop starting    node in the list*/   Node  *     detectAndgetLoopstarting  (  Node     *  head  )   {      Node     *  slow_p     =     head       *  fast_p     =     head    *  loop_start  ;      //Start traversing list and detect loop      while     (  slow_p     &&     fast_p     &&     fast_p  ->  next  )      {      slow_p     =     slow_p  ->  next  ;      fast_p     =     fast_p  ->  next  ->  next  ;      /* If slow_p and fast_p meet then find    the loop starting node*/      if     (  slow_p     ==     fast_p  )      {      loop_start     =     getLoopstart  (  slow_p       head  );      break  ;      }      }      // Return starting node of loop      return     loop_start  ;   }   // Utility function to check if a linked list with loop   // is palindrome with given starting point.   bool     isPalindromeUtil  (  Node     *  head       Node  *     loop_start  )   {      Node     *  ptr     =     head  ;      stack   <  int  >     s  ;      // Traverse linked list until last node is equal      // to loop_start and store the elements till start      // in a stack      int     count     =     0  ;      while     (  ptr     !=     loop_start     ||     count     !=     1  )      {      s  .  push  (  ptr  ->  data  );      if     (  ptr     ==     loop_start  )      count     =     1  ;      ptr     =     ptr  ->  next  ;      }      ptr     =     head  ;      count     =     0  ;      // Traverse linked list until last node is      // equal to loop_start second time      while     (  ptr     !=     loop_start     ||     count     !=     1  )      {      // Compare data of node with the top of stack      // If equal then continue      if     (  ptr  ->  data     ==     s  .  top  ())      s  .  pop  ();      // Else return false      else      return     false  ;      if     (  ptr     ==     loop_start  )      count     =     1  ;      ptr     =     ptr  ->  next  ;      }      // Return true if linked list is palindrome      return     true  ;   }   // Function to find if linked list is palindrome or not   bool     isPalindrome  (  Node  *     head  )   {      // Find the loop starting node      Node  *     loop_start     =     detectAndgetLoopstarting  (  head  );      // Check if linked list is palindrome      return     isPalindromeUtil  (  head       loop_start  );   }   Node     *  newNode  (  int     key  )   {      Node     *  temp     =     new     Node  ;      temp  ->  data     =     key  ;      temp  ->  next     =     NULL  ;      return     temp  ;   }   /* Driver program to test above function*/   int     main  ()   {      Node     *  head     =     newNode  (  50  );      head  ->  next     =     newNode  (  20  );      head  ->  next  ->  next     =     newNode  (  15  );      head  ->  next  ->  next  ->  next     =     newNode  (  20  );      head  ->  next  ->  next  ->  next  ->  next     =     newNode  (  50  );      /* Create a loop for testing */      head  ->  next  ->  next  ->  next  ->  next  ->  next     =     head  ->  next  ->  next  ;      isPalindrome  (  head  )  ?     cout      < <     '  n  Palindrome'      :     cout      < <     '  n  Not Palindrome'  ;      return     0  ;   }   
Java
   // Java program to check if a linked list   // with loop is palindrome or not.   import     java.util.*  ;   class   GfG      {   /* Link list node */   static     class   Node      {         int     data  ;         Node     next  ;      }   /* Function to find loop starting node.    loop_node --> Pointer to one of    the loop nodes head --> Pointer to    the start node of the linked list */   static     Node     getLoopstart  (  Node     loop_node           Node     head  )      {         Node     ptr1     =     loop_node  ;         Node     ptr2     =     loop_node  ;         // Count the number of nodes in loop       int     k     =     1       i  ;         while     (  ptr1  .  next     !=     ptr2  )         {         ptr1     =     ptr1  .  next  ;         k  ++  ;         }         // Fix one pointer to head       ptr1     =     head  ;         // And the other pointer to k       // nodes after head       ptr2     =     head  ;         for     (  i     =     0  ;     i      <     k  ;     i  ++  )         ptr2     =     ptr2  .  next  ;         /* Move both pointers at the same pace     they will meet at loop starting node */      while     (  ptr2     !=     ptr1  )         {         ptr1     =     ptr1  .  next  ;         ptr2     =     ptr2  .  next  ;         }         return     ptr1  ;      }      /* This function detects and find    loop starting node in the list*/   static     Node     detectAndgetLoopstarting  (  Node     head  )      {         Node     slow_p     =     head       fast_p     =     head    loop_start     =     null  ;         //Start traversing list and detect loop       while     (  slow_p     !=     null     &&     fast_p     !=     null     &&         fast_p  .  next     !=     null  )         {         slow_p     =     slow_p  .  next  ;         fast_p     =     fast_p  .  next  .  next  ;         /* If slow_p and fast_p meet then find     the loop starting node*/      if     (  slow_p     ==     fast_p  )         {         loop_start     =     getLoopstart  (  slow_p       head  );         break  ;         }         }         // Return starting node of loop       return     loop_start  ;      }      // Utility function to check if    // a linked list with loop is    // palindrome with given starting point.    static     boolean     isPalindromeUtil  (  Node     head        Node     loop_start  )      {         Node     ptr     =     head  ;         Stack   <  Integer  >     s     =     new     Stack   <  Integer  >     ();         // Traverse linked list until last node       // is equal to loop_start and store the       // elements till start in a stack       int     count     =     0  ;         while     (  ptr     !=     loop_start     ||     count     !=     1  )         {         s  .  push  (  ptr  .  data  );         if     (  ptr     ==     loop_start  )         count     =     1  ;         ptr     =     ptr  .  next  ;         }         ptr     =     head  ;         count     =     0  ;         // Traverse linked list until last node is       // equal to loop_start second time       while     (  ptr     !=     loop_start     ||     count     !=     1  )         {         // Compare data of node with the top of stack       // If equal then continue       if     (  ptr  .  data     ==     s  .  peek  ())         s  .  pop  ();         // Else return false       else      return     false  ;         if     (  ptr     ==     loop_start  )         count     =     1  ;         ptr     =     ptr  .  next  ;         }         // Return true if linked list is palindrome       return     true  ;      }      // Function to find if linked list   // is palindrome or not    static     boolean     isPalindrome  (  Node     head  )      {         // Find the loop starting node       Node     loop_start     =     detectAndgetLoopstarting  (  head  );         // Check if linked list is palindrome       return     isPalindromeUtil  (  head       loop_start  );      }      static     Node     newNode  (  int     key  )      {         Node     temp     =     new     Node  ();         temp  .  data     =     key  ;         temp  .  next     =     null  ;         return     temp  ;      }      /* Driver code*/   public     static     void     main  (  String  []     args  )      {         Node     head     =     newNode  (  50  );         head  .  next     =     newNode  (  20  );         head  .  next  .  next     =     newNode  (  15  );         head  .  next  .  next  .  next     =     newNode  (  20  );         head  .  next  .  next  .  next  .  next     =     newNode  (  50  );         /* Create a loop for testing */      head  .  next  .  next  .  next  .  next  .  next     =     head  .  next  .  next  ;         if  (  isPalindrome  (  head  )     ==     true  )      System  .  out  .  println  (  'Palindrome'  );      else      System  .  out  .  println  (  'Not Palindrome'  );      }   }      // This code is contributed by prerna saini   
Python
   # Python3 program to check if a linked list   # with loop is palindrome or not.   # Node class    class   Node  :   # Constructor to initialize the node object    def   __init__  (  self     data  ):   self  .  data   =   data   self  .  next   =   None   # Function to find loop starting node.    # loop_node -. Pointer to one of    # the loop nodes head -. Pointer to    # the start node of the linked list   def   getLoopstart  (  loop_node    head  ):   ptr1   =   loop_node   ptr2   =   loop_node   # Count the number of nodes in loop    k   =   1   i   =   0   while   (  ptr1  .  next   !=   ptr2  ):   ptr1   =   ptr1  .  next   k   =   k   +   1   # Fix one pointer to head    ptr1   =   head   # And the other pointer to k    # nodes after head    ptr2   =   head   i   =   0   while   (   i    <   k   )   :   ptr2   =   ptr2  .  next   i   =   i   +   1   # Move both pointers at the same pace    #they will meet at loop starting node */   while   (  ptr2   !=   ptr1  ):   ptr1   =   ptr1  .  next   ptr2   =   ptr2  .  next   return   ptr1   # This function detects and find    # loop starting node in the list   def   detectAndgetLoopstarting  (  head  ):   slow_p   =   head   fast_p   =   head   loop_start   =   None   # Start traversing list and detect loop    while   (  slow_p   !=   None   and   fast_p   !=   None   and   fast_p  .  next   !=   None  )   :   slow_p   =   slow_p  .  next   fast_p   =   fast_p  .  next  .  next   # If slow_p and fast_p meet then find    # the loop starting node   if   (  slow_p   ==   fast_p  )   :   loop_start   =   getLoopstart  (  slow_p     head  )   break   # Return starting node of loop    return   loop_start   # Utility function to check if    # a linked list with loop is    # palindrome with given starting point.    def   isPalindromeUtil  (  head     loop_start  ):   ptr   =   head   s   =   []   # Traverse linked list until last node    # is equal to loop_start and store the    # elements till start in a stack    count   =   0   while   (  ptr   !=   loop_start   or   count   !=   1  ):   s  .  append  (  ptr  .  data  )   if   (  ptr   ==   loop_start  )   :   count   =   1   ptr   =   ptr  .  next   ptr   =   head   count   =   0   # Traverse linked list until last node is    # equal to loop_start second time    while   (  ptr   !=   loop_start   or   count   !=   1  ):   # Compare data of node with the top of stack    # If equal then continue    if   (  ptr  .  data   ==   s  [  -  1  ]):   s  .  pop  ()   # Else return False    else  :   return   False   if   (  ptr   ==   loop_start  )   :   count   =   1   ptr   =   ptr  .  next   # Return True if linked list is palindrome    return   True   # Function to find if linked list   # is palindrome or not    def   isPalindrome  (  head  )   :   # Find the loop starting node    loop_start   =   detectAndgetLoopstarting  (  head  )   # Check if linked list is palindrome    return   isPalindromeUtil  (  head     loop_start  )   def   newNode  (  key  )   :   temp   =   Node  (  0  )   temp  .  data   =   key   temp  .  next   =   None   return   temp   # Driver code   head   =   newNode  (  50  )   head  .  next   =   newNode  (  20  )   head  .  next  .  next   =   newNode  (  15  )   head  .  next  .  next  .  next   =   newNode  (  20  )   head  .  next  .  next  .  next  .  next   =   newNode  (  50  )   # Create a loop for testing    head  .  next  .  next  .  next  .  next  .  next   =   head  .  next  .  next   if  (  isPalindrome  (  head  )   ==   True  ):   print  (  'Palindrome'  )   else  :   print  (  'Not Palindrome'  )   # This code is contributed by Arnab Kundu   
C#
   // C# program to check if a linked list   // with loop is palindrome or not.   using     System  ;   using     System.Collections.Generic  ;      class     GfG      {   /* Link list node */   class     Node      {         public     int     data  ;         public     Node     next  ;      }   /* Function to find loop starting node.    loop_node --> Pointer to one of    the loop nodes head --> Pointer to    the start node of the linked list */   static     Node     getLoopstart  (  Node     loop_node           Node     head  )      {         Node     ptr1     =     loop_node  ;         Node     ptr2     =     loop_node  ;         // Count the number of nodes in loop       int     k     =     1       i  ;         while     (  ptr1  .  next     !=     ptr2  )         {         ptr1     =     ptr1  .  next  ;         k  ++  ;         }         // Fix one pointer to head       ptr1     =     head  ;         // And the other pointer to k       // nodes after head       ptr2     =     head  ;         for     (  i     =     0  ;     i      <     k  ;     i  ++  )         ptr2     =     ptr2  .  next  ;         /* Move both pointers at the same pace     they will meet at loop starting node */      while     (  ptr2     !=     ptr1  )         {         ptr1     =     ptr1  .  next  ;         ptr2     =     ptr2  .  next  ;         }         return     ptr1  ;      }      /* This function detects and find    loop starting node in the list*/   static     Node     detectAndgetLoopstarting  (  Node     head  )      {         Node     slow_p     =     head       fast_p     =     head    loop_start     =     null  ;         //Start traversing list and detect loop       while     (  slow_p     !=     null     &&     fast_p     !=     null     &&         fast_p  .  next     !=     null  )         {         slow_p     =     slow_p  .  next  ;         fast_p     =     fast_p  .  next  .  next  ;         /* If slow_p and fast_p meet then find     the loop starting node*/      if     (  slow_p     ==     fast_p  )         {         loop_start     =     getLoopstart  (  slow_p       head  );         break  ;         }         }         // Return starting node of loop       return     loop_start  ;      }      // Utility function to check if    // a linked list with loop is    // palindrome with given starting point.    static     bool     isPalindromeUtil  (  Node     head        Node     loop_start  )      {         Node     ptr     =     head  ;         Stack   <  int  >     s     =     new     Stack   <  int  >     ();         // Traverse linked list until last node       // is equal to loop_start and store the       // elements till start in a stack       int     count     =     0  ;         while     (  ptr     !=     loop_start     ||     count     !=     1  )         {         s  .  Push  (  ptr  .  data  );         if     (  ptr     ==     loop_start  )         count     =     1  ;         ptr     =     ptr  .  next  ;         }         ptr     =     head  ;         count     =     0  ;         // Traverse linked list until last node is       // equal to loop_start second time       while     (  ptr     !=     loop_start     ||     count     !=     1  )         {         // Compare data of node with the top of stack       // If equal then continue       if     (  ptr  .  data     ==     s  .  Peek  ())         s  .  Pop  ();         // Else return false       else      return     false  ;         if     (  ptr     ==     loop_start  )         count     =     1  ;         ptr     =     ptr  .  next  ;         }         // Return true if linked list is palindrome       return     true  ;      }      // Function to find if linked list   // is palindrome or not    static     bool     isPalindrome  (  Node     head  )      {         // Find the loop starting node       Node     loop_start     =     detectAndgetLoopstarting  (  head  );         // Check if linked list is palindrome       return     isPalindromeUtil  (  head       loop_start  );      }      static     Node     newNode  (  int     key  )      {         Node     temp     =     new     Node  ();         temp  .  data     =     key  ;         temp  .  next     =     null  ;         return     temp  ;      }      /* Driver code*/   public     static     void     Main  (  String  []     args  )      {         Node     head     =     newNode  (  50  );         head  .  next     =     newNode  (  20  );         head  .  next  .  next     =     newNode  (  15  );         head  .  next  .  next  .  next     =     newNode  (  20  );         head  .  next  .  next  .  next  .  next     =     newNode  (  50  );         /* Create a loop for testing */      head  .  next  .  next  .  next  .  next  .  next     =     head  .  next  .  next  ;         if  (  isPalindrome  (  head  )     ==     true  )      Console  .  WriteLine  (  'Palindrome'  );      else      Console  .  WriteLine  (  'Not Palindrome'  );      }   }   /* This code is contributed by 29AjayKumar */   
JavaScript
    <  script  >   // javascript program to check if a linked list   // with loop is palindrome or not.class GfG {      /* Link list node */      class     Node     {      constructor  ()     {      this  .  data     =     0  ;      this  .  next     =     null  ;      }      }      /*    * Function to find loop starting node. loop_node --> Pointer to one of the loop    * nodes head --> Pointer to the start node of the linked list    */      function     getLoopstart  (  loop_node       head  )     {      var     ptr1     =     loop_node  ;      var     ptr2     =     loop_node  ;      // Count the number of nodes in loop      var     k     =     1       i  ;      while     (  ptr1  .  next     !=     ptr2  )     {      ptr1     =     ptr1  .  next  ;      k  ++  ;      }      // Fix one pointer to head      ptr1     =     head  ;      // And the other pointer to k      // nodes after head      ptr2     =     head  ;      for     (  i     =     0  ;     i      <     k  ;     i  ++  )      ptr2     =     ptr2  .  next  ;      /*    * Move both pointers at the same pace they will meet at loop starting node    */      while     (  ptr2     !=     ptr1  )     {      ptr1     =     ptr1  .  next  ;      ptr2     =     ptr2  .  next  ;      }      return     ptr1  ;      }      /*    * This function detects and find loop starting node in the list    */      function     detectAndgetLoopstarting  (  head  )     {      var     slow_p     =     head       fast_p     =     head       loop_start     =     null  ;      // Start traversing list and detect loop      while     (  slow_p     !=     null     &&     fast_p     !=     null     &&     fast_p  .  next     !=     null  )     {      slow_p     =     slow_p  .  next  ;      fast_p     =     fast_p  .  next  .  next  ;      /*    * If slow_p and fast_p meet then find the loop starting node    */      if     (  slow_p     ==     fast_p  )     {      loop_start     =     getLoopstart  (  slow_p       head  );      break  ;      }      }      // Return starting node of loop      return     loop_start  ;      }      // Utility function to check if      // a linked list with loop is      // palindrome with given starting point.      function     isPalindromeUtil  (  head       loop_start  )     {      var     ptr     =     head  ;      var     s     =     [];      // Traverse linked list until last node      // is equal to loop_start and store the      // elements till start in a stack      var     count     =     0  ;      while     (  ptr     !=     loop_start     ||     count     !=     1  )     {      s  .  push  (  ptr  .  data  );      if     (  ptr     ==     loop_start  )      count     =     1  ;      ptr     =     ptr  .  next  ;      }      ptr     =     head  ;      count     =     0  ;      // Traverse linked list until last node is      // equal to loop_start second time      while     (  ptr     !=     loop_start     ||     count     !=     1  )     {      // Compare data of node with the top of stack      // If equal then continue      var     stk     =     s  .  pop  ();      if     (  ptr  .  data     ==     stk  );          // Else return false      else  {      s  .  push  (  stk  );      return     false  ;      }      if     (  ptr     ==     loop_start  )      count     =     1  ;      ptr     =     ptr  .  next  ;      }      // Return true if linked list is palindrome      return     true  ;      }      // Function to find if linked list      // is palindrome or not      function     isPalindrome  (  head  )     {      // Find the loop starting node      var     loop_start     =     detectAndgetLoopstarting  (  head  );      // Check if linked list is palindrome      return     isPalindromeUtil  (  head       loop_start  );      }      function     newNode  (  key  )     {      var     temp     =     new     Node  ();      temp  .  data     =     key  ;      temp  .  next     =     null  ;      return     temp  ;      }      /* Driver code */          var     head     =     newNode  (  50  );      head  .  next     =     newNode  (  20  );      head  .  next  .  next     =     newNode  (  15  );      head  .  next  .  next  .  next     =     newNode  (  20  );      head  .  next  .  next  .  next  .  next     =     newNode  (  50  );      /* Create a loop for testing */      head  .  next  .  next  .  next  .  next  .  next     =     head  .  next  .  next  ;      if     (  isPalindrome  (  head  )     ==     true  )      document  .  write  (  'Palindrome'  );      else      document  .  write  (  'Not Palindrome'  );   // This code contributed by aashish1995     <  /script>   

Wyjście
Palindrome 

Złożoność czasowa: O(n) 
Przestrzeń pomocnicza: O(n) 

 

Utwórz quiz