通过单链表判断字符串是否为回文字符串?

实现思路

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)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code tea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值