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

版权声明:Please make the source marked https://blog.csdn.net/qq_31807385/article/details/86254979

题目:

给定一个链表的头结点是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))

第三种实现方案,实现的思路是将后半部分的链表倒置,然后这个链表链表分别从两点开始遍历,对比元素是否是相等的,然后再将链表还原。

猜你喜欢

转载自blog.csdn.net/qq_31807385/article/details/86254979