zoukankan      html  css  js  c++  java
  • 链表回文判断(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/』
  • 相关阅读:
    LeetCode 230. 二叉搜索树中第K小的元素(Kth Smallest Element in a BST)
    LeetCode 216. 组合总和 III(Combination Sum III)
    LeetCode 179. 最大数(Largest Number)
    LeetCode 199. 二叉树的右视图(Binary Tree Right Side View)
    LeetCode 114. 二叉树展开为链表(Flatten Binary Tree to Linked List)
    LeetCode 106. 从中序与后序遍历序列构造二叉树(Construct Binary Tree from Inorder and Postorder Traversal)
    指针变量、普通变量、内存和地址的全面对比
    MiZ702学习笔记8——让MiZ702变身PC的方法
    你可能不知道的,定义,声明,初始化
    原创zynq文章整理(MiZ702教程+例程)
  • 原文地址:https://www.cnblogs.com/xiaoxi666/p/7284332.html
Copyright © 2011-2022 走看看