算法总结之 判断一个链表是否是回文结构

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

1->2->1 返回true

进阶: 如果链表长度N,时间复杂度O(N) 额外空间O(1)

方法一

利用栈结构(需要额外空间)

从左到右遍历,一次压栈。   这样的到的  从栈顶到栈底的节点值出现顺序会与原链表从左到右的值出现顺序相反。

废话不多说,上代码:

package TT;

import java.util.Stack;

public class Test92 {

    public class Node{
        public int value;
        public Node next;

        public Node(int data){
            this.value = 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.value !=stack.pop().value){
                return false;
            }
            head = head.next;
        }
          return true;
        }

}

进阶:

方法二    对上面的进行优化,不需要所有的节点都压入栈中 压入一半即可

前 N/2的节点叫做左半区,后N/2叫做右半区。 N为奇数 忽略处于最中间的节点,还是   前 N/2的节点叫做左半区,后N/2叫做右半区

相当于折纸  折回去

package TT;

import java.util.Stack;

import TT.Test85.Node;

public class Test93 {

    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;
    }

}

方法三 改变结构   不需要栈和其他数据结构 只用有限几个变量 其额外空间复杂度O(1)

1 首先改变链表右半区的机构 使整个右半区反转 最后指向中间节点     看图一目了然

package TT;

import TT.Test84.Node;

public class Test94 {

    public boolean isPalindrome2(Node head){
         if(head==null || head.next==null){
             return true;
         }

         Node n1 = head;
         Node n2 = head;
         while(n2.next !=null && n2.next.next != null){
                  n1=n1.next;
                  n2=n2.next.next;
         }

         n2 = n1.next;
         n1.next=null;
         Node n3 =null;
         while(n2 != null){
             n3=n2.next;
             n2.next=n1;
             n1=n2;
             n2=n3;
         }
         n3=n1;
         n2=head;
         boolean res = true;

         while(n1 !=null && n2 !=null){

             if(n1.value != n2.value){
                 res = false;
                 break;
             }

             n1 =n1.next;
             n2=n2.next;

         }

         n1 = n3.next;
         n3.next = null;

         while(n1 != null){
             n2 = n1.next;
             n1.next = n3;
             n3=n1;
             n1=n2;

         }

         return res;
    }

}
时间: 2024-12-05 07:01:38

算法总结之 判断一个链表是否是回文结构的相关文章

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

给定一个链表的头节点head, 请判断该链表是否为回文结构. 例如: 1->2->1, 返回true. 1->2->2->1, 返回true.15->6->15, 返回true. 1->2->3, 返回false.进阶: 如果链表长度为N, 时间复杂度达到O(N), 额外空间复杂度达到O(1). 原文地址:https://www.cnblogs.com/SkyeAngel/p/8747901.html

左神算法书籍《程序员代码面试指南》——2_06判断一个链表是否为回文结构

[题目]给定一个链表的头节点head,请判断该链表是否为回文结构.例如:1->2->1,返回true.1->2->2->1,返回true.15->6->15,返回true.1->2->3,返回false.进阶:如果链表长度为N,时间复杂度达到O(N),额外空间复杂度达到O(1).[题解]方法一:遍历一遍链表,将数据压入栈中然后再遍历一遍链表与栈的弹出数据对比方法二:使用快慢指针,将链表的前部分压入栈,然后栈数据弹出与链表的后半部分对比方法三:使用快慢指

【算法】如何判断一个二叉树是平衡二叉树

题目:如何判断一个二叉树是平衡二叉树 定义: 平衡二叉树(AVL):1.空二叉树是AVL树: 2.如果T是一颗非空的二叉搜索树,TL和TR分别是其左子树和右子树,那么当T满足一下条件时,T是一颗AVL树:(1)TL和TR是AVL树:(2)|HL-HR|<=1,HL和HR分别是左子树和右子树的高度 示例: 算法思想: 采用递归的思想,从root节点进行递归的调用.假设叶子节点的高度是0,分别计算各个节点的左右子树的高度差:若高度差大于1则返回-1(表示不是平衡树)否则返回子树的最大高度加一. 时间

C++算法之 倒序输出一个链表

题目:给定一个头结点,倒叙输出一个链表 解法1:先将链表反转,在遍历输出 解法2:不修改链表自身的结构,动态申请一段空间,申请一个指针数组,数组内存放的指针指向链表的每个值,再遍历数组输出: void PrintListBack(ListNode* head) { int n = GetLength(head); ListNode** p = new ListNode*[n+1]; p[n] = NULL; int i = 0; ListNode* pNode = head; while (i

Linked List Cycle 判断一个链表是否存在回路(循环)

Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using extra space? 注意,链表循环并不是尾指针和头指针相同,可能是在中间某一段形成一个环路,所以不能只判断元素和第一个元素是否存在重合 先设置两个指针p_fast和p_slow.从头开始遍历链表,p_fast每次走两个节点,而p_slow每次走一个节点,若存在循环,这两个指针必定重合: 1 /**

判断一个链表是否有环

思路:如果开始有两个指针指向头结点,一个走的快,一个走的慢,如果有环的话,最终经过若干步,快的指针总会超过慢的指针一圈从而相遇. 如何计算环的长度呢?可以第一次相遇时开始计数,第二次相遇时停止计数. 如何判断环的入口点?碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点.头指针开始走,相遇的那个点就是连接点. 当fast与slow相遇时,show肯定没有走完链表,而fast已经在还里走了n(n>= 1)圈.假设slow走了s步,那么fast走了2s步.fast的步数还等于s走的加上

点在多边形内算法,C#判断一个点是否在一个复杂多边形的内部

判断一点是否在不规则图像的内部算法,如下图是由一个个点组成的不规则图像,判断某一点是否在不规则矩形内部,先上效果图 算法实现如下,算法简单,亲试有效 public class PositionAlgorithmHelper { /// <summary> /// 判断当前位置是否在不规则形状里面 /// </summary> /// <param name="nvert">不规则形状的定点数</param> /// <param n

判断一个链表是不是回文链表

第一种方法: 额外空间复杂度O(N) ,遍历链表时,将元素入栈,再次遍历时,从栈中弹出元素,比较两者的大小,就可以判断是不是回文链表第二种方法:利用快慢指针,先找到链表的中间位置,然后反转链表的后半部分,再分别从链表两头遍历比较大小,最后将链表恢复为原始结构 public class PalindromeLinkedList { public static void main(String[] args) { Node head = new Node(1); head.next = new No

判断一个链表是否有环的几种方法

一.单链表是否有环 思路分析: 单链表有环,是指单链表中某个节点的next指针域指向的是链表中在它之前的某一个节点,这样在链表的尾部形成一个环形结构.判断链表是否有环,有以下几种方法. 1 // 链表的节点结构如下 2 typedef struct node 3 { 4 int data; 5 struct node *next; 6 } NODE; (1)最常用方法:定义两个指针,同时从链表的头节点出发,一个指针一次走一步,另一个指针一次走两步.如果走得快的指针追上了走得慢的指针,那么链表就是