• 判断回文链表


    问题描述

    请判断一个链表是否为回文链表。链表为单向无环链表

    示例 1:

    输入: 1->2
    输出: false

    示例 2:

    输入: 1->2->2->1
    输出: true

    解法一:

    这题是让判断链表是否是回文链表,所谓的回文链表就是以链表中间为中心点两边对称。我们常见的有判断一个字符串是否是回文字符串,这个比较简单,可以使用两个指针,一个最左边一个最右边,两个指针同时往中间靠,判断所指的字符是否相等。

    但这题判断的是链表,因为这里是单向链表,只能从前往后访问,不能从后往前访问,所以使用判断字符串的那种方式是行不通的。但我们可以通过找到链表的中间节点然后把链表后半部分反转,最后再用后半部分反转的链表和前半部分一个个比较即可。这里以示例2为例画个图看一下。

     

     最后再来看下代码:

     public boolean isPalindrome(ListNode head) {
            ListNode slow = head, fast = head;
            //快慢指针
            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
            }
            //如果fast不为空,说明链表的长度是奇数个
            if (fast != null) {
               slow=slow.next;
            }
            //反转后半部分链表
            slow = reverse(slow);
            fast=head;
            while (slow!=null){
                //不是回文
                if (fast.val!=slow.val){
                    return false;
                }
                slow=slow.next;
                fast=fast.next;
            }
            return true;
        }
    
        //反转链表
        public ListNode reverse(ListNode head) {
            ListNode pre = null;
            while (head != null) {
                ListNode next = head.next;
                head.next = pre;
                pre = next;
                head = next;
            }
            return pre;
        }

    解法二:

    我们知道栈是先进后出的一种数据结构,这里还可以使用栈先把链表的节点全部存放到栈中,然后再一个个出栈,这样就相当于链表从后往前访问了,通过这种方式也能解决,看下代码:

    public boolean isPalindrome1(ListNode head) {
            if (head == null) {
                return true;
            }
            ListNode temp = head;
            Stack<Integer> stack = new Stack();
            int len = 0;
            while (temp != null) {
                stack.push(temp.val);
                temp = temp.next;
                len++;
            }
            //长度除以2
            len >>= 1;
            while (len-- > 0) {
                if (head.val != stack.pop()) {
                    return false;
                }
                head = head.next;
            }
            return true;
        }

    解法三(递归):

      ListNode temp;
        public boolean isPalindrome2(ListNode head) {
            temp = head;
            return  check(temp);
        }
        private boolean check(ListNode head) {
            if (head == null){
                return  true;
            }
            //逆序打印链表
            boolean res = check(head.next) && (temp.val == head.val);
            temp = temp.next;
            return res;
        }

    总结:

    回文链表的判断,相比回文字符串的判断稍微要麻烦一点,但难度也不是很大,如果对链表比较熟悉的话,这3种解决方式都很容易想到,如果不熟悉的话,可能最容易想到的就是第2种了,也就是栈和链表的结合。

  • 相关阅读:
    Firefox扩展IE Tab Plus内置功能导致浏览所有网页加载superfish.com脚本
    iconv编码转换
    Firefox扩展IE Tab Plus内置功能导致浏览所有网页加载superfish.com脚本
    mysql导入邮件
    Rails gem 打包css javascript 提升网站性能 jammit 简介
    装箱/拆箱测试一例(转)
    nifity scaffold gem
    软硬链接
    软硬链接
    git服务搭建
  • 原文地址:https://www.cnblogs.com/xiaofeng-fu/p/13937924.html
Copyright © 2020-2023  润新知