zoukankan      html  css  js  c++  java
  • LeetCode-234. 回文链表

    题目描述

    请判断一个链表是否为回文链表。

    示例 1:

    输入: 1->2
    输出: false
    示例 2:

    输入: 1->2->2->1
    输出: true

    进阶:
    你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

    思路

    数组加双指针

    首先给出一个比较简单明了的思路,双指针。还记得用双指针的方法来判断回文字符串,但是单链表无法反向进行索引,需要先将单链表转换成数组再进行判断。

    bool isPalindrome(ListNode* head) {
        vector<int> listVal;
        while(head)
        {
            listVal.push_back(head->val);
            head = head->next;
        }
        int iPre = 0;
        int iEnd = listVal.size() - 1;
        while(iPre < iEnd)
        {
            if(listVal[iPre] != listVal[iEnd])
                return false;
            iPre++;
            iEnd--;
        }
        return true;
    }
    

    反转单链表解法

    找到单链表的中间结点。

    • 链表长度为奇数(2n+1)时索引为n。
      如1->2->3->2->1, 则中间结点为3.
    • 链表长度为偶数2n时为n-1。
      如1->2->3->3->2->1, 则中间结点为第一个3.

    将中间结点之后的一半链表进行反转。

    反转之后只需要进行一次扫描就可以得出结论。
    如1->2->3->2->1经过反转之后变为1->2->3->1->2。
    1->2->3->3->2->1经过反转之后变为1->2->3->3->2->1。

    接下来要解决的两个问题就是如何找到链表的中间的结点和如何反转链表。

    链表中间结点的确定可以采取快慢指针的方法,快指针每次循环前进两步,慢指针每次循环前进一步,当快指针到达链表的结尾时,慢指针指向的结点恰好是链表的中间结点。
    ListNode *fast = head;
    ListNode *slow = head;
    while(fast->next != NULL && fast->next->next!= NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    
    反转单链表仍然可以采用双指针的方法。
    ListNode* reverseList(ListNode *head)
    {
        ListNode *pre = NULL;
        ListNode *next = NULL;
        while(head != NULL)
        {
            next = head->next;
            head->next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }
    

    以链表1->2->3->4->5为例简单分析下上述代码的反转过程。
    1 2->3->4->5
    1<-2 3->4->5
    1<-2<-3 4->5
    1<-2<-3<-4 5
    1<-2<-3<-4<-5

    最终解法。

    bool isPalindromePro(ListNode* head)
    {
        if(head == NULL || head->next == NULL)
            return true;
        ListNode *fast = head;
        ListNode *slow = head;
        while(fast->next != NULL && fast->next->next != NULL)
        {
            fast = fast->next->next;
            slow = slow->next;
        }
        slow->next = reverseList(slow->next);
        slow = slow->next;
        while(slow != NULL)
        {
            if(head->val != slow->val)
                return false;
            head = head->next;
            slow = slow->next;
        }
        return true;
    }
    
    ListNode* reverseList(ListNode *head)
    {
        ListNode *pre = NULL;
        ListNode *next = NULL;
        while(head != NULL)
        {
            next = head->next;
            head->next = pre;
            pre = head;
            head = next;
        }
        return pre;
    }
    
  • 相关阅读:
    在github上搭建hexo博客
    Docker镜像命令笔记
    Scrapy学习1:安装
    Android安全初学笔记
    Python数据结构01 线性结构
    IOS开发之__bridge,__bridge_transfer和__bridge_retained (转)
    设置字体样式 TTF
    NYTimes Objective-C 编程风格指南
    MQTT简介
    如何将自己编写的app放到真机上运行
  • 原文地址:https://www.cnblogs.com/BlueskyRedsea/p/9326666.html
Copyright © 2011-2022 走看看