赞
踩
链表的回文结构,即 1 --> 2 --> 3 --> 2 --> 1 这样的形式,链表正着和反过来是一样的。
思路:
1、将原链表进行拷贝;
2、对拷贝的链表进行逆置;
3、然后比较逆置之后的链表和原链表是否相同。
public boolean chkPalindrome(ListNode A) { // 1 判断特殊情况,即链表为空和链表只有一个结点的情况 // 此时,必定是回文结构 if (A == null || A.next == null) { return true; } // 2 先拷贝一份原链表,不破坏原来的链表 ListNode newHead = new ListNode(0); ListNode newTail = newHead; for(ListNode node = A;node != null;node = node.next) { newTail.next = new ListNode(node.val); newTail = newTail.next; } // 3 用三指针法,即 prev、cur、next 来逆置链表 ListNode prev = null; ListNode cur = newHead.next; while (cur != null) { ListNode next = cur.next; cur.next = prev; prev = cur; cur = next; } ListNode curReverseA = prev; // 4 比较逆置之后的链表和原链表是否相同 ListNode curA = A; while (curReverseA != null && curA != null) { if (curA.val == curReverseA.val) { curA = curA.next; curReverseA = curReverseA.next; } else { return false; } } return true; }
思路:
1、不用新创建链表,直接在原链表上进行操作;
2、求得链表的长度,然后读取到一半的元素;
3、对一半的元素进行逆置;
4、然后将逆置后的半个链表与剩下的未逆置的一半链表进行比较。
private static int getLength(ListNode head) { int length = 0; for (ListNode cur = head;cur != null; cur = cur.next) { length ++; } return length; } public static boolean chkPalindrome(ListNode A) { // 1、先将特殊情况考虑罗列出来 if (A == null || A.next == null) { return true; } // 2、读取到前半个链表 int len = getLength(A); int steps = len / 2; ListNode B = A; for (int i = 0; i < steps; i++) { B = B.next; } // 3、将这前半个链表进行逆置 ListNode prev = null; ListNode cur = B; while (cur != null) { ListNode next = cur.next; cur.next = prev; prev = cur; cur = next; } B = prev; // 4、比较逆置了的前半个链表和未逆置的后半个链表 ListNode cur1 = A; ListNode cur2 = B; while (cur1 != null && cur2 != null) { if (cur1.val != cur2.val) { return false; } cur1 = cur1.next; cur2 = cur2.next; } return true; }
注意:
链表结点为奇数个和偶数个的时候,链表的样子是不一样的,但是代码是一致的。
偶数个时,因为 cur1 != null && cur2 != null 这个条件,只要一个为null,循环就会结束了。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。