判断链表是是否是回文
2017-10-25 12:02
387 查看
>
/* * Node class * @author lhs */ public class Node { public Object value; public Node next; public Node(Object data){ this.value = data; } }
import java.util.Scanner; import java.util.Stack; /** * 判断一个链表是是否是回文结构 * 进阶:如果链表的长度为N,时间复杂度达到O(N),额外的空间复杂度是O(1)。 * @author lhs94 * @date 2017-10-24 */ public class JudgePalindromel { public static void main(String[] args) { JudgePalindromel test = new JudgePalindromel(); Scanner sc = new Scanner(System.in); Node head; //使用尾插法构造单链表 while(sc.hasNextLine()){ String[] input = sc.nextLine().split(" "); head = new Node(input[0]); Node tailNode = head;//tailNode指向尾节点 for (int i = 1; i < input.length; i++) { Node node = new Node(input[i]); tailNode.next = node;//把新节点定义为新的尾节点 tailNode = node; } tailNode.next = null;//尾节点结束 boolean result1 = test.isPalindromel_1(head); System.out.println("result :" + result1 ); boolean result2 = test.isPalindromel_2(head); System.out.println("result :" + result2 ); boolean result3 = test.isPalindromel_3(head); System.out.println("result :" + result3 ); } } /** * 使用栈来判断,因为若是回文,进栈的顺序和出栈的顺序是一样的。否则不是回文 * 此方法的时间复杂度是O(N),空间复杂度也是O(N) * @param head * @return */ public boolean isPalindromel_1(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.equals(stack.pop().value)){ return false; } head = head.next; } return true; } /** * 可以把优化上面的栈的实现,因为若是回文,那么并不需要把所有的元素都入栈中,只压入一半即可。 * 假设链表的长度是N,如果N是偶数,那么,前N/2的节点叫做左半区,后N/2叫做后半区; * 如果是奇数,忽略中间的那个数,还是前一半是左半区,后一半是右半区; * 把后一半压入栈中,然后比较栈顶到栈底的元素与链表的前一半是否一样。 * 此方法的时间复杂度是O(N),空间复杂度是O(N/2). * @param head * @return */ public boolean isPalindromel_2(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.equals(stack.pop().value)){ return false; } head = head.next; } return true; } /** * 进阶: * 不需要栈和其他数据结构,只用有限的几个变量,其额外空间复杂度是O(1),可以在时间复杂度为O(N)内完成所有的过程。 * 1.首先改变链表右边区的结构,使整个右边区反转,最后指向中间节点; * 2.leftStart 和rightStart 同时向中间点移动,移动每一步,比较leftStart和rightStart的节点的值,看是否一样。 * 若一样,说明是回文,否则不是回文。 * 3.不管最后返回的是true 还是 false,在返回前,都应该把链表恢复成原来的样子。 * 4.链表恢复成原来的结构后,返回检查结果。 * @param head * @return */ public boolean isPalindromel_3(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;//n1 -> 中部 n2 = n2.next.next;// n2 -> 结尾 } n2 = n1.next;//右半部分第一个节点 n1.next = null;// mid.next -->null Node n3 = null; while(n2 != null){ n3 = n2.next;// n3-->保存下一个节点 n2.next = n1;//下一个反转节点 n1 = n2;//n1移动 n2 = n3;//n2移动 } n3 = n1;//n3保存最后一个节点 n2 = head;//n2-->左边第一个节点 boolean result = true; while(n1 != null && n2 != null){//检查回文 if(!n1.value.equals(n2.value)){//对象判断是否相等,需用equeals(),"=="判断时是不相等的,即使内容一样 result = 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 result; } }
相关文章推荐
- 判断一个链表是否为回文结构
- 链表问题---判断一个链表是否为回文结构
- [分析总结:leetcode-Palindrome Linked List] 给定单链表,判断链表是否为回文。
- 链表之判断一个链表是否为回文结构(二)
- C++数据结构与算法之判断一个链表是否为回文结构的方法
- 链表之判断一个链表是否为回文结构(三)
- 链表逆序+判断链表是否回文
- 判断一个链表是否为回文结构
- 《程序员面试金典》--判断链表是否为回文链表
- LeetCode 234. Palindrome Linked List判断链表是否回文
- 判断一个链表是否回文(每日一道算法题)
- 如何判断一个单向链表是否为回文链表(Palindrome Linked List)
- Palindrome Linked List 判断链表是否回文 栈实现
- java判断一个链表是否是回文结构
- Palindrome Linked List - LeetCode 判断一个链表是否是回文结构
- 链表:判断是否回文
- 判断链表是否回文
- 判断一个链表是否是回文链表
- LeetCode234_PalindromeLinkedList (判断是否为回文链表) Java题解
- 234. Palindrome Linked List 判断链表是否回文(C++解决)