• 链表回文判断(C++)


    
    

    题目描述:

    对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
    给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
    测试样例:
    1->2->2->1

    返回:true

    思路:  
      由于空间复杂度要求为O(1),也就是说临时占用空间和输入数据规模无关,因此无法利用数组或者是栈进行判断。因此先找到中间位置将后半部分指针翻转,然后两端分别比较。注意这种方法会修改原链表,但是空间复杂度要求为O(1)也只能这么做了。

    程序运行流程:
      1、利用快慢指针找到中间的位置(起初均指向头结点,然后pSlow一次走一步,pFast一次走两步。注意不需要区分链表结点个数是奇数还是偶数);
      2、将后半部分指针翻转;
      3、最后再进行一次遍历,一个从前向后,一个从后向前。

    下图是演示图(分为
    链表结点个数奇数和偶数两种情况),当pFast或pFast->next到达尾部(为NULL)时,pSlow正好到达中间位置。其中当链表结点个数为偶数时,pFast首先变为NULL;当链表结点个数为奇数时,pFast->next首先变为NULL。

      

       

      

       

    代码:

      1 /*
      2 本程序说明:
      3 
      4 时间限制:3秒 空间限制:32768K 热度指数:8332
      5 本题知识点: 链表 栈
      6 
      7 题目描述
      8 对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
      9 给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
     10 测试样例:
     11 1->2->2->1
     12 返回:true
     13 
     14 */
     15 
     16 #include <iostream>
     17 using namespace std;
     18 
     19 struct ListNode {
     20     int val;
     21     struct ListNode *next;
     22     ListNode(int x) : val(x), next(NULL) {}
     23 };
     24 
     25 //链表结点构造
     26 ListNode*  create_list_node(int val)
     27 {
     28     ListNode* pNode = new ListNode(val);
     29     return pNode;
     30 }
     31 //链表结点连接
     32 void connect_list_node(ListNode* pCur, ListNode* pNext)
     33 {
     34     pCur->next = pNext;
     35 }
     36 
     37 
     38 
     39 class PalindromeList {
     40 public:
     41     bool chkPalindrome(ListNode* A) {
     42         // write code here
     43         ListNode* pSlow = A;
     44         ListNode* pFast = A;
     45 
     46         while(pFast != NULL && pFast->next != NULL)
     47         {
     48             pSlow = pSlow->next;
     49             pFast = pFast->next->next;
     50         }
     51         //反转链表后半部分指针
     52         ListNode* prev = pSlow;//临时保存用
     53         pSlow = pSlow->next;
     54         prev->next = NULL;//最中间的点的next置为NULL
     55         while(pSlow != NULL)
     56         {
     57             cout<<pSlow->val<<endl;
     58             ListNode* tmp = pSlow->next;//保存后面的结点
     59             pSlow->next=prev;
     60             prev = pSlow;
     61             pSlow = tmp;
     62         }
     63 
     64         ListNode* pForward = A;//指向头结点
     65         ListNode* pBackward= prev;//指向链表最后一个结点
     66 
     67         while(!(pForward == pBackward || pForward->next == pBackward))
     68         {
     69             if(pForward->val != pBackward->val)
     70                 return false;
     71             pForward = pForward->next;
     72             pBackward = pBackward->next;
     73         }
     74         return true;
     75     }
     76 };
     77 
     78 void test()
     79 {
     80     //创建结点
     81     ListNode* pNode1 = create_list_node(1);
     82     ListNode* pNode2 = create_list_node(1);
     83     ListNode* pNode3 = create_list_node(7);
     84     ListNode* pNode4 = create_list_node(2);
     85     ListNode* pNode5 = create_list_node(7);
     86     ListNode* pNode6 = create_list_node(1);
     87     ListNode* pNode7 = create_list_node(1);
     88 //    ListNode* pNode8 = create_list_node(45);
     89 //    ListNode* pNode9 = create_list_node(-7);
     90 
     91     //连接结点
     92     connect_list_node(pNode1,pNode2);
     93     connect_list_node(pNode2,pNode3);
     94     connect_list_node(pNode3,pNode4);
     95     connect_list_node(pNode4,pNode5);
     96     connect_list_node(pNode5,pNode6);
     97     connect_list_node(pNode6,pNode7);
     98 //    connect_list_node(pNode7,pNode8);
     99 //    connect_list_node(pNode8,pNode9);
    100 
    101     PalindromeList test;
    102 
    103     bool flag=test.chkPalindrome(pNode1);
    104     cout<<flag<<endl;
    105 
    106 }
    107 
    108 int main()
    109 {
    110     test();
    111     return 0;
    112 }

    欢迎交流。


    
    
    『注:本文来自博客园“小溪的博客”,若非声明均为原创内容,请勿用于商业用途,转载请注明出处http://www.cnblogs.com/xiaoxi666/』
  • 相关阅读:
    C#TreeView 添加 右键快捷菜单
    Zlib Usage
    C3499 a lambda that has been specified to have a void return type cannot return a value
    Question Need to Find out
    C++ wstring转string
    C# TabPage隐藏问题
    设置IIS支持INI文件下载
    SQL SERVER CTE查询
    compression format and tools
    C++11的for循环,以及范围Range类的实现
  • 原文地址:https://www.cnblogs.com/xiaoxi666/p/7284332.html
Copyright © 2020-2023  润新知