您的位置:首页 > 其它

[分析总结:leetcode-Palindrome Linked List] 给定单链表,判断链表是否为回文。

2015-07-14 15:15 363 查看
原题链接: https://leetcode.com/problems/palindrome-linked-list/
题目描述:

1. 介绍什么事回文:就是正着念,反着念都一样的词句,比如:“习主席”,比如“李总理”。。。举个例子,如“1,2,3,4,3,2,1”,从中间对称分开,往两端延展时是对称的。

2. 单链表:链表中的数据是以节点来表示的,每个结点的构成:元素(数据元素的映象)
+ 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

基本思想:

要判断回文结构,需要找到链表的中间点,然后从中间点向两边顺序延展,判断每次延展的元素值是否相等。从中间点向两边延展,就涉及到链表的正序和逆序遍历问题。对于单链表,逆序时比较麻烦,但也把握住中心思想,麻烦的事情自然会有它的解决办法。另外,这里面最讲究的地方,其实是找到中间点。

引申问题 --- 链表的逆序遍历

1. 最直接的方式:链表时头指向尾的单项序列,如果需要逆序遍历,那么最简单的办法就是把单链表的顺序都倒过来,尾指向头。这样的话,就能做到逆向遍历。对于我这样的强迫症患者来说,总觉得对于单链表,这种办法改变了原本的数据顺序,总是不好。其实没什么,这一点需要克服克服。大不了判断回文以后咱们再给它恢复回去。

public Node reverse(Node head){
Node preNode = null;
Node curr = head;
Node next = null;

while(curr != null){
next = curr.next;
curr.next = preNode;
preNode = curr;
curr = next;
}
}


2. 对强迫症患者最舒服的方式:配合栈的LIFO特点。先正序遍历你的单链表,同时把每个元素都压入栈中。然后让栈把数据一个一个吐出来。这样的话栈吐出的数据顺序就是逆序的了。

引申问题 --- 链表中间点的寻找

1. 最直接的办法: 正向遍历一遍单链表,遍历完了你能知道链表长度 = length。然后找到中间点:mid = (length%2 == 1)?[(int)(length/2) + 1] : length/2。

2. 巧妙一点的办法:设置两个指针同时指向表头,然后开始遍历,区别是一个指针的遍历跨度为1(singlePtr),另一个指针的遍历跨度为2(doublePtr)。当doublePtr走到链表尾端时,singlePtr正好到中点。

那么接下来我就贴出我自己的解法-- 双指针 + 栈

/**
* Definition for singly-linked list.
* public class ListNode {
*     int val;
*     ListNode next;
*     ListNode(int x) { val = x; }
* }
*/
public class Solution {
public boolean isPalindrome(ListNode head) {
ListNode doublePtr = head;
ListNode singlePtr = head;

Stack<ListNode> nodeStack = new Stack<ListNode>();

while(doublePtr != null && doublePtr.next != null){
nodeStack.push(singlePtr);
singlePtr = singlePtr.next;
doublePtr = doublePtr.next.next;
}

if(doublePtr != null){
singlePtr = singlePtr.next;
}

while(!nodeStack.empty() && singlePtr != null){
if(nodeStack.pop().val != singlePtr.val){
return false;
}

singlePtr = singlePtr.next;
}

return true;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: