数据结构习题--回文链表

数据结构习题--回文链表

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false

要求:

时间复杂度为O(n)

空间复杂度为O(1)

方法:反转后半链表

分析

因为要求使用O(1)空间复杂度,否则我们可以直接反转链表在一个一个比较,而因为不能开拓这种空间来存储链表,所以这里我们采取把原来的链表的后半部分反转,再与原来的链表的前半部分进行比较

  1. 先找到链表的中点
  2. 判断该链表奇偶,对慢指针进行处理
  3. 一一比较

代码

java 复制代码
package LinkList;

public class PalindromeList {
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode() {}
     *     ListNode(int val) { this.val = val; }
     *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
     * }
     */
    public class ListNode {
          int val;
          ListNode next;
          ListNode() {}
          ListNode(int val) { this.val = val; }
          ListNode(int val, ListNode next) { this.val = val; this.next = next; }
      }
    class Solution {
        public boolean isPalindrome(ListNode head) {
            // 初始快慢指针
            ListNode fast = head;
            ListNode slow = head;
            // 这里采用的是反转后半部分链表的方法,当然也可以反转前面链表,大概流程差不多
            // 快指针每次移动两格,慢指针每次一格,当快指针跑到结尾时,慢指针恰好在中间
            while (fast != null && fast.next != null){
                fast = fast.next.next;
                slow = slow.next;
            }
            // 原来的链表分为奇数和偶数情况
            // 当是奇数情况时,最中间那个元素不用判断回文,而慢指针指向最中间那个元素,所以单独往后移动一格慢指针
            // 比如:12345 结束循环时,快指针在5,慢指针在3,而我们其实只需要反转45就行
            // 对于偶数链表: 1234,结束循环时,快指针在(1234null)中的null,慢指针在3.我们需要反转34
            // 所以当快指针不为null时,说明链表是奇数,需要处理慢指针
            if (fast != null){
                slow = slow.next;
            }
            // 反转后面链表
            slow = reverse(slow);
            // 快指针重新指向头结点
            fast = head;
            // 逐一比较每个结点
            while (slow != null){
                if (fast.val != slow.val){
                    return false;
                }
                fast = fast.next;
                slow = slow.next;
            }
            return true;
        }
        public ListNode reverse(ListNode head) {
            ListNode nextNode = null;
            ListNode preNode = null;
            while (head != null){
                nextNode = head.next;
                head.next = preNode;
                preNode = head;
                head = nextNode;
            }
            return preNode;
        }
    }
}
相关推荐
Darling噜啦啦5 天前
列表转树算法深度解析:从 Map 到 Reduce 的两种实现,面试高频考点
数据结构·算法·面试
小小工匠6 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
玖玥拾6 天前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
Qres8217 天前
算法复键——树状数组
数据结构·算法
牛油果子哥q7 天前
并查集(DSU)超精讲,路径压缩、按秩合并、万能模板、连通性判定、最小生成树与刷题实战全解
数据结构·c++·最小生成树·并查集
凌波粒7 天前
LeetCode--491.递增子序列(回溯算法)
数据结构·算法·leetcode
疯狂成瘾者7 天前
Java 集合 LinkedList 详解:链表结构、常用方法和队列使用
java·开发语言·链表
WL学习笔记7 天前
单项不带头不循环链表
数据结构·链表
小糯米6017 天前
JS 数组
数据结构·算法·排序算法
小欣加油7 天前
leetcode3612 用特殊操作处理字符串I
数据结构·c++·算法·leetcode·职场和发展