判断单链表是否为回文
2016-07-10 21:15
239 查看
这道题很有意思,你能在O(1) space,O(n) time约束下做出来吗?
让我们来一步一步观察,思考。
回文,那么意味着是轴对称的,想到用比较最左端和最右端的方法,可是这在单链表上是根本没法做的,除非是双向链表,但题目也不允许修改数据结构啊,所以不可行。再想想,把链表逆转吧,但是逆转之后怎么办?失去了比较对象啊。再想想,那逆转一半如何?如果是回文的话,前半段和后半段就必须是一样的。好,这方法靠谱,下一步是找到中间的结点,如果结点数是奇数,则直接返回中间结点;如果为偶数,应该返回靠右的结点。这个求中间结点的代码为:
好的,然后链表逆转的算法。
然后,这道题就可以这么写。
嘻嘻。
让我们来一步一步观察,思考。
回文,那么意味着是轴对称的,想到用比较最左端和最右端的方法,可是这在单链表上是根本没法做的,除非是双向链表,但题目也不允许修改数据结构啊,所以不可行。再想想,把链表逆转吧,但是逆转之后怎么办?失去了比较对象啊。再想想,那逆转一半如何?如果是回文的话,前半段和后半段就必须是一样的。好,这方法靠谱,下一步是找到中间的结点,如果结点数是奇数,则直接返回中间结点;如果为偶数,应该返回靠右的结点。这个求中间结点的代码为:
ListNode * getMiddle(ListNode *head) { ListNode *p1 = head,*p2 = head; while (p2 && p2->next) { p1 = p1->next; p2 = p2->next->next; } return p1; }
好的,然后链表逆转的算法。
ListNode * reverseLink(ListNode *head) { ListNode *p1 = nullptr; ListNode *p2 = head; while(p2){ ListNode *t = p2->next; p2->next = p1; p1 = p2; p2 = t; } return p1; }
然后,这道题就可以这么写。
bool isPalindrome(ListNode *head){ ListNode *mid = getMiddle(head); ListNode *right = reverseLink(mid); for(;head && right; head=head->next,right=right->next) { if(head->val != right->val) return false; } return true; }
嘻嘻。
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#实现单链表(线性表)完整实例
- C#定义并实现单链表实例解析
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- C语言实现单链表逆序与逆序输出实例
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C语言单链表常见操作汇总
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- C数据结构之单链表详细示例分析
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- 【数据结构与算法】数组应用4:多项式计算Java版