思路
- 1、快慢两个指针同时从头结点出发,快指针每次两步,慢指针每次1步,直到快指针到尾节点,慢指针刚好到中间位置,
- 2、同时将中间位置之前的字符串用一个单链表逆序存储
- 3、依次比较中间位置两边的字符串是否相等,即可判断字符串是否回文
package com.lxd.leetcode.demo;
import java.util.Scanner;
/**
* @author lxd
* @version 1.0.0
* @create 2020-06-20 16:52
* @desc 判断一个字符串是否有回文
**/
public class StringPlalindrome {
/****
* 1、快慢两个指针同时从头结点出发,快指针每次两步,慢指针每次1步,直到快指针到尾节点,慢指针刚好到中间位置,
* 2、同时将中间位置之前的字符串用一个单链表逆序存储
* 3、依次比较中间位置两边的字符串是否相等,即可判断字符串是否回文
*/
/***
* 定义单向链接的节点类 ,两个属性,data、下一个节点
*/
static class ListNode {
private int data;
private ListNode next;
public ListNode(int data) {
this.data = data;
}
}
/****
* 1、链表头结点做参数
* 2、校验链表
* 3、定义快慢两个指针
* 4、定义一个空节点(逆序存储中间节点之前的字符串会用到)
* 5、移动快慢两个指针,同时逆序存储慢指针指向的节点
* 6、移动慢指针到中间节点后一位
* 7、依次比较中间节点两边的字符串是否相等
*/
public static boolean isPalindroom(ListNode head) {
//校验链表
if (head == null || head.next == null) {
return true;
}
//定义两个指针
ListNode fast = head;
ListNode slow = head;
//逆序存储字符串的尾节点
ListNode pre = null;
while (fast != null && fast.next != null) {
//快指针未到达尾节点
//快指针移动两步
fast = fast.next.next;
//临时变量存储slow的next节点
ListNode next = slow.next;
//将头结点的下一个节点指向NULL
slow.next = pre;
//pre指向逆序链表的头结点
pre = slow;
//慢指针移动到next
slow = next;
}
if (fast != null) {
//移动慢指针到中间节点后一位
slow = slow.next;
}
while (slow != null) {
//慢指针不到尾节点
if (pre.data != slow.data) {
return false;
}
//两个链表指针依次向后走
slow = slow.next;
pre = pre.next;
}
return true;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String temp = scanner.nextLine();
char[] s = temp.toCharArray();
ListNode[] node = new ListNode[s.length];
for (int i = 0; i < s.length; i++) {
node[i] = new ListNode(s[i]);
}
for (int i = 0; i < s.length; i++) {
if (i == s.length - 1) {
node[i].next = null;
} else {
node[i].next = node[i + 1];
}
}
boolean flag = StringPlalindrome.isPalindroom(node[0]);
System.out.println("链表是回文吗? " + flag);
}
}