• [LeetCode] 234. Palindrome Linked List


    Given a singly linked list, determine if it is a palindrome.

    Example 1:

    Input: 1->2
    Output: false

    Example 2:

    Input: 1->2->2->1
    Output: true

    Follow up:
    Could you do it in O(n) time and O(1) space?

    回文链表。题意是给一个链表,判断是不是回文链表。思路是快慢指针找到链表中点,reverse后半段,然后比较前半和后半。题目要求不能使用额外空间,其实是不太可能的,除非直接在input的链表上做操作。

    二刷的时候有一个疑问,找到的链表中点,如果整个链表的节点数为奇数,中点在哪?节点数为偶数,中点又在哪?我跑了一个例子帮助加强记忆,如下图,图中数字表示节点的index。当找中间节点的函数跑完的时候,如果节点数是偶数个,则s停在3的位置;如果节点数是奇数个,则s停在2的位置。后半部分的head节点是slow.next所以后半部分的head节点分别是4和3(偶数,奇数)。

    reverse后半部分,则对于第一个例子,比较的是123和654两个链表;对于第二个例子,比较的是12和543两个链表。又因为while循环的时候判断的是两个链表同时不为空,所以当链表节点个数为奇数的时候,也能判断input是否为回文链表。

    1 - 2 - 3 - 4 - 5 - 6

    s    f

    1 - 2 - 3 - 4 - 5

    s    f

    时间O(n) - 题目要求

    空间O(1) - 题目要求

    JavaScript实现

     1 /**
     2  * @param {ListNode} head
     3  * @return {boolean}
     4  */
     5 var isPalindrome = function(head) {
     6     if (head === null) return true;
     7     let middle = findMiddle(head);
     8     middle.next = reverse(middle.next);
     9 
    10     let p = head;
    11     let q = middle.next;
    12     while (p !== null && q !== null) {
    13         if (p.val !== q.val) {
    14             return false;
    15         }
    16         p = p.next;
    17         q = q.next;
    18     }
    19     return true;
    20 };
    21 
    22 var findMiddle = function(head) {
    23     let slow = head;
    24     let fast = head.next;
    25     while (fast !== null && fast.next !== null) {
    26         slow = slow.next;
    27         fast = fast.next.next;
    28     }
    29     return slow;
    30 }
    31 
    32 var reverse = function(head) {
    33     let pre = null;
    34     while (head !== null) {
    35         let next = head.next;
    36         head.next = pre;
    37         pre = head;
    38         head = next;
    39     }
    40     return pre;
    41 }

    最后注意代码里面24行定义fast pointer的方式。

    Java实现

     1 /**
     2  * Definition for singly-linked list.
     3  * public class ListNode {
     4  *     int val;
     5  *     ListNode next;
     6  *     ListNode(int x) { val = x; }
     7  * }
     8  */
     9 class Solution {
    10     public boolean isPalindrome(ListNode head) {
    11         // corner case
    12         if (head == null) {
    13             return true;
    14         }
    15         // normal case
    16         ListNode middle = findMiddle(head);
    17         middle.next = reverse(middle.next);
    18         ListNode p1 = head;
    19         ListNode p2 = middle.next;
    20         while (p1 != null && p2 != null) {
    21             if (p1.val != p2.val) {
    22                 return false;
    23             } else {
    24                 p1 = p1.next;
    25                 p2 = p2.next;
    26             }
    27         }
    28         return true;
    29     }
    30 
    31     private ListNode findMiddle(ListNode head) {
    32         ListNode slow = head;
    33         ListNode fast = head;
    34         while (fast.next != null && fast.next.next != null) {
    35             slow = slow.next;
    36             fast = fast.next.next;
    37         }
    38         return slow;
    39     }
    40 
    41     private ListNode reverse(ListNode head) {
    42         ListNode pre = null;
    43         while (head != null) {
    44             ListNode next = head.next;
    45             head.next = pre;
    46             pre = head;
    47             head = next;
    48         }
    49         return pre;
    50     }
    51 }

    相关题目

    125. Valid Palindrome

    234. Palindrome Linked List

    680. Valid Palindrome II

    LeetCode 题目总结

  • 相关阅读:
    DataTable:数据库到程序的桥梁
    《Javascript高级程序设计》阅读记录(三):第五章 上
    《Javascript高级程序设计》阅读记录(二):第四章
    javascript获取窗口位置、绝对位置、事件位置等
    《Javascript高级程序设计》阅读记录(一):第二、三章
    调试用随笔
    C#值类型和引用类型
    vue使用vue-awesome-swiper及一些问题
    npm与yarn命令对比
    npm与nrm
  • 原文地址:https://www.cnblogs.com/cnoodle/p/11828939.html
Copyright © 2020-2023  润新知