美文网首页算法
判断链表是否是回文结构

判断链表是否是回文结构

作者: 一凡呀 | 来源:发表于2017-12-07 15:08 被阅读0次

    题目:

    image.png

    思路1:

    需要建立一个辅助栈,把链表入栈,如果链表从头节点开始和每次弹出的节点相同,说明是回文结构

    代码一:

    public static class Node {
            public int value;
            public Node next;
    
            public Node(int data) {
                this.value = data;
            }
        }
    
        // need n extra space
        public static boolean isPalindrome1(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.value != stack.pop().value) {
                    return false;
                }
                head = head.next;
            }
            return true;
        }
    

    思路2:

    建立一个大小为n/2的辅助栈,然后建立两个指针,cur和right,cur每次移动两步,right每次移动一步,right的初始值是head.next,这样当cur到最后了,right刚好在中间结点的右边,然后,从right开始入栈,弹出比较,相同就说明是回文结构

    代码2:

    // need n/2 extra space
        public static boolean isPalindrome2(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.value != stack.pop().value) {
                    return false;
                }
                head = head.next;
            }
            return true;
        }
    
    

    思路3:

    不用建立辅助栈,通过改变指针的指向即可,改变完指向,链表方向从两边指向中间。
    首先,建立指针n1,n2,n1每次右移1位,n2每次移动两位,最后n1停在中间,n2停在最后,然后创建一个新变量n3,用于交换时临时存储信息,n2移动到n1.next,然后n1.next=null,然后循环,n3存储n2.next,用于在改变依次链表方向后,继续修改时更新n2的值,n2.next=n1,n1=n2,n2=n3,当n2==null说明指针放心都改变完成了。然后让n3=n1,n2=head,开始比较过程。比较过程和之前一样,比较完成后,要复原链表原来的结构,这时用n1和n2都停在中间节点上,让n1=n3.next,n3.next=null,这次用n2来临时存储信息,n2=n1.next,n3.next=n1,n1=n3,n3=n2,当n1=null时跳出循环说明改回原来的结构了

    代码3:

        // need O(1) extra space
        public static boolean isPalindrome3(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.value != n2.value) {
                    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 main(String[] args) {
        
                Node head = null;
                printLinkedList(head);
                System.out.print(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(head) + " | ");
                printLinkedList(head);
                System.out.println("=========================");
        
                head = new Node(1);
                printLinkedList(head);
                System.out.print(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(head) + " | ");
                printLinkedList(head);
                System.out.println("=========================");
        
                head = new Node(1);
                head.next = new Node(2);
                printLinkedList(head);
                System.out.print(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(head) + " | ");
                printLinkedList(head);
                System.out.println("=========================");
        
                head = new Node(1);
                head.next = new Node(1);
                printLinkedList(head);
                System.out.print(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(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(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(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(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(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(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(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(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(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(isPalindrome1(head) + " | ");
                System.out.print(isPalindrome2(head) + " | ");
                System.out.println(isPalindrome3(head) + " | ");
                printLinkedList(head);
                System.out.println("=========================");
        
            }
    
    

    相关文章

      网友评论

        本文标题:判断链表是否是回文结构

        本文链接:https://www.haomeiwen.com/subject/tgfdixtx.html