zoukankan      html  css  js  c++  java
  • 判断回文链表

    问题描述

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

    示例 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种了,也就是栈和链表的结合。

  • 相关阅读:
    Silverlight & Blend动画设计系列三:缩放动画(ScaleTransform) from http://www.cnblogs.com/beniao/archive/2010/03/26/1694157.html
    基于知识库的信息推荐系统
    观察者模式之:一个游戏设想
    Expression Blend制作画卷效果 from http://www.cnblogs.com/alexis/archive/2010/12/23/1915402.html
    为了忘却的生活
    C 文件读写
    VC++中,CString,in,char,等数据类型的相互转化 from:http://blog.csdn.net/heaven13483/article/details/7553176
    【ML2】最小二乘法(least squares)介绍
    机器学习的基本概念
    【ML95】SVM的sklearn.svm.SVC()函数应用
  • 原文地址:https://www.cnblogs.com/xiaofeng-fu/p/13937924.html
Copyright © 2011-2022 走看看