判断一个链表是否为回文结构

题目描述

给定一个链表的头节点head,请判断该链表是否为回文结构。
例如: 1->2->1,返回true。
1->2->2->1,返回true。
15->6->15,返回true。
1->2->3,返回false。
进阶: 如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1)。

思路

链表相关的问题,笔试时尽快做出来即可,空间复杂度可以高一些;面试时要使空间复杂度低。
方法一:第一遍遍历链表时把值依次压入栈中,第二次遍历链表时,从栈中弹出一个数进行对比,全部一样则是回文结构,否则不是。
方法二:快指针走两步,慢指针走一步,快指针走完时,慢指针到链表中间位置,此时开始压栈,把链表的后半部分压入栈中。然后从头开始遍历链表,同时从栈中弹出节点进行比较,当栈中的数都弹完时,若没有出现不一致的,则是回文结构,否则不是回文结构。
方法三:还是用两个指针,一个一次走一步,一个一次走两步,这样找到中间的节点(奇数个的时候就是最中间的节点,偶数个的时候找到最中间的两个节点中较烤前的那个)。然后把后半段链表逆序,next指针指的方向反过来,中间节点的next指针指向空。接着两个指针从链表的两端开始遍历。

代码

package LinearStructure;

import java.util.Stack;

public class IsPalindromeList {

    public static class Node{
        public int val;
        public Node next;
        public Node(int data){ this.val = data; }
    }

    // 需要n额外空间
    public static boolean isPalindromeList1(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.val != stack.pop().val)
                return false;
            head=head.next;
        }
        return true;
    }

    // 需要2/n额外空间
    public static boolean isPalindromeList2(Node head){
        if (head == null || head.next == null)
            return true;
        Node right = head;
        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.val != stack.pop().val)
                return false;
            head=head.next;
        }
        return true;
    }

    //需要0(1)额外空间
    public static boolean isPalindromeList3(Node head){
        if (head == null || head.next == null) {
            return true;
        }
        Node n1 = head;
        Node n2 = head;
        while (n2.next != null && n2.next.next != null) { // find mid node
            n1 = n1.next; // n1 -> mid
            n2 = n2.next.next; // n2 -> end
        }
        n2 = n1.next; // n2 -> right part first node
        n1.next = null; // mid.next -> null
        Node n3 = null;
        while (n2 != null) { // right part convert
            n3 = n2.next; // n3 -> save next node
            n2.next = n1; // next of right node convert
            n1 = n2; // n1 move
            n2 = n3; // n2 move
        }
        n3 = n1; // n3 -> save last node
        n2 = head;// n2 -> left first node
        boolean res = true;
        while (n1 != null && n2 != null) { // check palindrome
            if (n1.val != n2.val) {
                res = false;
                break;
            }
            n1 = n1.next; // left to mid
            n2 = n2.next; // right to mid
        }
        n1 = n3.next;
        n3.next = null;
        while (n1 != null) { // recover list
            n2 = n1.next;
            n1.next = n3;
            n3 = n1;
            n1 = n2;
        }
        return res;
    }



    public static void printLinkedList(Node node) {
        System.out.print("Linked List: ");
        while (node != null) {
            System.out.print(node.val + " ");
            node = node.next;
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Node head = null;
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(2);
        head.next.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");

        head = new Node(1);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(2);
        head.next.next.next.next = new Node(1);
        printLinkedList(head);
        System.out.print(isPalindromeList1(head) + " | ");
        System.out.print(isPalindromeList2(head) + " | ");
        System.out.println(isPalindromeList3(head) + " | ");
        printLinkedList(head);
        System.out.println("=========================");
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值