第十一题:判断一个链表是否为回文结构(Java实现)

题目:

    给定一个链表的头结点是head,请判断该链表是否为回文结构

    例如:

    1->2->1,返回true

    1->2->2->1,返回true

    1->2->3,返回false

分析:

在链表问题中,时间复杂度一般都是O(n)的,所以链表的优化一般在空间复杂度上的优化,在笔试和面试中,面对链表的问题,我们的策略是不一样的,如果是在笔试中,不用考虑优化的问题,应该赶紧将当前的题目过掉,不需要考虑空间如何优化的问题,但是在面试的过程中,就应该建立在时间复杂度为O(1),尽可能的去降低额外的空间复杂度。
代码实现1(时间复杂度O(1),额外空间复杂度O(n)):

    package com.isea.brush;
     
    import java.util.Stack;
     
    /**
     * 判断一个链表是否是回文结构
     * 实现思路:
     * 使用一个辅助的栈结构,第一次遍历链表的时候将所有的元素都放入到栈中
     * 第二次遍历链表的时候,依次取出栈中的元素,然后对比元素的值是否相等。
     *
     */
    public class Palindrome {
        
        private class Node{
            private int data;
            private Node next;
            public Node(int data){
                this.data = data;
            }
        }
        
        public static boolean isPalindrome(Node head){
            Stack<Node> stack = new Stack<Node>();
            Node cur = head;
            while (cur != null){
                stack.push(cur);
                cur = cur.next;
            }
            while (head != null ){
                if (head.data != stack.pop().data) {
                    return false;
                }
                head = head.next;
            }
            return true;
        }
    }

代码实现二:(时间复杂度O(1),额外空间复杂度O(n))

    package com.isea.brush;
     
    import java.util.Stack;
     
    /**
     * 判断一个链表是否是回文结构
     * 实现思路:
     * 使用一个辅助的栈结构,再使用两指针 ,一个快指针,一个慢指针,当快指针走完整个链表的时候,慢指针刚好来到链表。
     * 中间的位置,此时从中间的位置开始将剩余链表中的元素放入到栈中;然后重头开始遍历链表,栈中的元素也依次弹出。
     * 如果栈为空的时候,还没有出现元素不相等的情况的话,那么该链表是回文结构。
     * 相比较于第一种方法,这样的方法能够节省一半的空间,但是额外空间复杂度还是O(n)的。
     * 这里值得注意的是:无论链表的长度是奇数还是偶数,都需要保证慢指针在后半部分的起点
     *
     */
    public class Palindrome {
     
        private class Node{
            private int data;
            private Node next;
            public Node(int data){
                this.data = data;
            }
        }
     
        public static boolean isPalindrome(Node head){
            if (head == null && head.next == null){
                return true;
            }
            
            Node right = head.next;
            Node cur = head;
            while(cur.next != null && cur.next.next != null){
                right = right.next;
                cur = cur.next.next;
            }
            
            Stack<Node> stack = new Stack<Node>();
            while(right != null){
                stack.push(right);
                right = right.next;
            }
            
            while(!stack.isEmpty()){
                if (head.data != stack.pop().data){
                    return false;
                }
                head = head.next;
            }
            return true;
        }
    }

代码实现三:(时间复杂度O(1),额外空间复杂度O(1))

第三种实现方案,实现的思路是将后半部分的链表倒置,然后这个链表链表分别从两点开始遍历,对比元素是否是相等的,然后再将链表还原。
---------------------
作者:isea_you
来源:CSDN
原文:https://blog.csdn.net/qq_31807385/article/details/86254979
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-07-27 20:55  天涯海角路  阅读(241)  评论(0)    收藏  举报