[分析总结: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. 最直接的方式:链表时头指向尾的单项序列,如果需要逆序遍历,那么最简单的办法就是把单链表的顺序都倒过来,尾指向头。这样的话,就能做到逆向遍历。对于我这样的强迫症患者来说,总觉得对于单链表,这种办法改变了原本的数据顺序,总是不好。其实没什么,这一点需要克服克服。大不了判断回文以后咱们再给它恢复回去。
2. 对强迫症患者最舒服的方式:配合栈的LIFO特点。先正序遍历你的单链表,同时把每个元素都压入栈中。然后让栈把数据一个一个吐出来。这样的话栈吐出的数据顺序就是逆序的了。
引申问题 --- 链表中间点的寻找
1. 最直接的办法: 正向遍历一遍单链表,遍历完了你能知道链表长度 = length。然后找到中间点:mid = (length%2 == 1)?[(int)(length/2) + 1] : length/2。
2. 巧妙一点的办法:设置两个指针同时指向表头,然后开始遍历,区别是一个指针的遍历跨度为1(singlePtr),另一个指针的遍历跨度为2(doublePtr)。当doublePtr走到链表尾端时,singlePtr正好到中点。
那么接下来我就贴出我自己的解法-- 双指针 + 栈
题目描述:
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; } }
相关文章推荐
- sizeof总结(转载)
- 1、Task类构造函数
- Android视频渲染: YUV转RGB
- PS给图片添加阴影方法
- JVM --并发垃圾回收器CMS
- List和ArrayList的区别
- java实现基于SGIP协议开发联通短信的方法
- Centos7 安装maven,tomcat(linux第三篇)
- C++类内存分布
- 系统架构优化思路
- Android -- 使用Fragment
- X264编码的一些收藏
- linux中svn命令集
- NSDateFormatter用法
- 数据库设计三大范式
- app应用分析
- Linux测试标准------stress压力测试
- jQuery原型方法first,last,eq,slice源码分析
- Wireshark数据抓包教程之安装Wireshark
- 科技公司未来会在哪些领域混战?