判断单链表存储的字符串是否为“回文串”

难度:二星

回文串是啥?我想不用解释了,如果不懂什么是回文串可以自己百度一下。

这里讲解的是当使用单链表来存储一个字符串的时候,如何通过单链表这种存储结构,判断这个字符串是不是回文串。

先说下思想:

我们使用快慢两个指针,初始状态下快指针和慢指针都指向单链表的头结点。快指针每次走两步,慢指针每次走一步,一直到快指针走到单链表的最后一个结点位置。此时慢指针恰巧会走到字符串的中间位置。如果我们能同时把中间位置之前的字符串在另一个单链表逆序存储。问题就非常简单了,依次比较中间位置两边每个字符是否相等即可判断是否是回文串了。

文字表达不够直观,那么我们通过图来表示。我觉得学习数据结构和算法动手画图、一步步跟踪算法的变化过程是一个直观的学习方法。我又不是计算机,我怎么可能凭空想象这个过程呢?脑容量明显不够嘛!如果能用图表示出来,一定会加深理解的。学习的方法是举例子和画图。

极客时间的王争老师说过,写链表代码是最考验逻辑思维能力的,因为链表代码到处都是指针操作、边界条件的处理,稍有不慎就会产生bug。链表写的好坏,可以看出一个人写代码是否足够细心,考虑问题是否全面,思维是否缜密

代码其实网上很多都实现了,我直接拿出来。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
  public boolean isPalindrome(ListNode head) {
    if (head == null || head.next == null) {
      return true;
    }

    ListNode prev = null;
    ListNode slow = head;
    ListNode fast = head;

    while (fast != null && fast.next != null) {
      fast = fast.next.next;
      ListNode next = slow.next;
      slow.next = prev;
      prev = slow;
      slow = next;
    }

    if (fast != null) {
      slow = slow.next;
    }

    while (slow != null) {
      if (slow.val != prev.val) {
        return false;
      }
      slow = slow.next;
      prev = prev.next;
    }

    return true;
  }
}

以回文串abcba为例,结合代码,我画图表示下这个过程。

判断单链表存储的字符串是否为“回文串”_第1张图片

 

判断单链表存储的字符串是否为“回文串”_第2张图片

经过两次循环我们最终得到了这样的结构:

判断单链表存储的字符串是否为“回文串”_第3张图片

接下来同时移动prev和slow指针比较值是否相等,一直到slow指向null为止。

不知道你有没有看懂?欢迎一起交流,如果你觉得哪里有问题,欢迎提出。

你可能感兴趣的:(算法与数据结构)