• 【LeetCode-链表】回文链表


    题目描述

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

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

    题目链接:https://leetcode-cn.com/problems/palindrome-linked-list/

    思路1

    回文链表就是正向遍历序列和反向遍历序列一样的链表,所以可以遍历链表一边,用队列记录链表的正向遍历序列,用栈记录反向遍历序列,然后比较即可。下面的代码没有用队列,用的是vector,其实是一样的。代码如下:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        bool isPalindrome(ListNode* head) {
            if(head==nullptr){
                return true;
            }
    
            vector<int> v;  // 记录正向遍历序列
            stack<int> s;   // 记录反向遍历序列
            while(head!=nullptr){
                v.push_back(head->val);
                s.push(head->val);
                head = head->next;
            }
    
            for(int i=0; i<v.size(); i++){
                int st = s.top();
                s.pop();
                if(v[i]!=st){
                    return false;
                }
            }
            return true;
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度: O(n)
      用到了vector和栈,辅助空间随着链表的增长而线性增长。

    思路2

    先将链表分为两部分,然后将第二部分(后一部分)翻转后与第一部分比较。
    将链表分为两部分可以先求链表长度n,然后找第n/2个节点。因为链表的长度可能为偶数和奇数,这两种情况下的分割是不一样的。当链表长度为偶数时,两条链表长度相等;当长度为奇数时,第一条链表的长度比第二条链表的长度大一,所以要翻转第二条链表并根据第二条链表比较。代码如下:

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        bool isPalindrome(ListNode* head) {
            if(head==nullptr || head->next==nullptr){
                return true;
            }
    
            /*分割链表*/
            ListNode* slow = head;
            ListNode* fast = head;
            while(fast->next!=nullptr && fast->next->next!=nullptr){
                fast = fast->next->next;
                slow = slow->next;
            }
            ListNode* head1 = head;
            ListNode* head2 = slow->next;
            slow->next = nullptr;
            
            /*翻转后一个链表*/
            ListNode* curNode = head2;
            ListNode* preNode = nullptr;
            ListNode* nextNode = nullptr;
            while(curNode!=nullptr){
                nextNode = curNode->next;
                curNode->next = preNode;
                preNode = curNode;
                curNode = nextNode;
            }
            head2 = preNode;
            
            while(head2!=nullptr){  // 注意要使用第2个链表,因为第2个链表长度小于等于第1个链表长度
                if(head1->val != head2->val){
                    return false;
                }
                head1 = head1->next;
                head2 = head2->next;
            }
            return true;
        }
    };
    
    • 时间复杂度: O(n)
    • 空间复杂度: O(1)
  • 相关阅读:
    iOS-多线程
    iOS-Quartz 2D
    iOS-手势识别
    iOS-触摸事件
    iOS-导航控制器
    iOS-程序的启动过程
    iOS-UIApplication
    iOS-项目常见文件
    iOS-UI控件常见属性总结
    iOS-UIDatePicker、UIPickerView及键盘处理
  • 原文地址:https://www.cnblogs.com/flix/p/12673432.html
Copyright © 2020-2023  润新知