zoukankan      html  css  js  c++  java
  • 判断一个链表是否是回文结构

    判断一个数是否回文数

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

    代码

    package Algorithms.linkedNode;
    
    /**
     * @author : zhang
     * @version : 1.0
     * @date : Create in 2021/8/10
     * @description :
     */
    
    
    import java.util.Stack;
    
    public class IsPalindromeList {
    
        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<Integer> stack = new Stack<>();
            Node cur = head;
            while (cur!=null){
                stack.push(cur.value);
                cur = cur.next;
            }
    
            while (head!=null){
                if (head.value!=stack.pop()){
                    return false;
                }
                head = head.next;
            }
            return true;
    
        }
    
        // need n/2 extra space  快慢指针:cur走1步,right走两步
        public static boolean isPalindrome2(Node head) {
            if (head == null || head.next == null) {
                return true;
            }
            Node cur = head;
            Node right = head.next;
    
            while (cur.next!=null && cur.next.next!=null){
                cur = cur.next;
                right = right.next;
            }
            Stack<Integer> stack = new Stack<>();
            while (right!=null){
                stack.push(right.value);
                right = right.next;
            }
            while(!stack.isEmpty()){
                if (head.value!=stack.pop()){
                    return false;
                }
                head = head.next;
            }
            return true;
        }
    
        // need O(1) extra space 面试用此方法回答(使用有限的几个变量)
        //过程举例:将 1 -> 2 -> 3 -> 2 -> 1 变为:1 -> 2 -> 3 <- 2 <- 1 进行比较
        //最后再变为1 -> 2 -> 3 -> 2 -> 1返回true
        //过程:
        //1、使用快慢指针:慢指针n1每次走1步,快指针n2每次走2步,快指针n2走到结尾的时候,慢指针n1来到中间位置
        //2、n1之后节点逆序(指向mid,3 <- 2 <- 1),逆序之后n1来到重点位置,n2为null
        //3、判断是否回文(左右两边进行比较)
        //4、后半部分再次进行逆序,保持原始结构
        public static boolean isPalindrome3(Node head) {
            if (head == null || head.next == null) {
                return true;
            }
            //1、快慢指针
            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;
            //2、逆序
            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
            }
            //3、判断是否回文
            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
            }
            //4、后半部分再次进行逆序,保持原始结构
            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.value + " ");
                node = node.next;
            }
            System.out.println();
        }
    
        public static void main(String[] args) {
    
            Node 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);
    
        }
    }
    
    /**
     * Linked List: 1 2 3 2 1
     * true | true | true |
     * Linked List: 1 2 3 2 1
     */
  • 相关阅读:
    Java Sping 第一章——初识 Spring
    C++设计模式——状态模式 State
    线性代数思维导图(3)——向量组
    基于Servlet实现简单系统登录
    优秀博客汇总
    整理一些开源项目
    Android UI性能优化详解
    (原创)如何在spannableString中使用自定义字体
    (原创)用讯飞语音实现人机交互的功能
    (原创)speex与wav格式音频文件的互相转换(二)
  • 原文地址:https://www.cnblogs.com/zh-xiaoyuan/p/15125845.html
Copyright © 2011-2022 走看看