通过单链表判断字符串是否为回文字符串?
实现思路
1. 找到中间节点(快慢指针法)
快慢指针定位中间节点: 快指针一次两格, 慢指针一次一格, 快指针遍历完的时候慢指针所在就是中点。(这里要区分奇偶情况)
2. 判断回文
慢指针到达中间节点的过程中还可以做一件事,把走过的节点反转方向。
然后在中间节点在开辟一个指针按反转的方向往回走, 慢指针继续向前, 当慢指针扫描完整个链表, 前后两段字符串反转方向后相等, 可以判断这是回文字符串。否则可以提前判断这个字符串不是回文字符串。
3. 还原字符串
新指针从中间节点往回走的过程中可以同时把反转过的节点还原为原来字符串的顺序。
Java实现
创建单向链表节点类
public class Node { private Node next; private Character value; public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } public Character getValue() { return value; } public Node() { } public Node(Character value) { this.value = value; } / * 根据字符串构造单向链表 * * @param str */ public static Node build(String str) { Node next = null; for (int i = str.length() - 1; i >= 0; i--) { Node node = new Node(str.charAt(i)); node.setNext(next); next = node; } return next; }}
判断回文字符串
/ * 判断单链表是否为回文字符串 * * @param node * @return */ public static boolean isReverse(Node node) { boolean result = true; //快指针 Node fast = node; //慢指针 Node slow = node; //用于回去的指针 Node back = null; //临时指针 Node last; //快指针一次两步 区分长度为奇数和偶数情况 //移动过程中, 慢指针进行反转 boolean first = true; while (fast.getNext() != null && fast.getNext().getNext() != null) { fast = fast.getNext().getNext(); last = back; back = slow; slow = slow.getNext(); back.setNext(last); } //偶数 if (fast.getNext() != null) { //回去的指针 last = back; back = slow; slow = slow.getNext(); back.setNext(last); }else{ //奇数 slow = slow.getNext(); } while (slow.getNext() != null) { if (!back.getValue().equals(slow.getValue())) { result = false; } last = back; back = back.getNext(); last.setNext(slow); slow = slow.getNext(); } return result; }
复杂度
时间复杂度O(n), 空间复杂度O(1)