关于LeetCode中Palindrome Linked List一题的理解
来源:互联网 发布:网络流行照片 编辑:程序博客网 时间:2024/06/07 02:37
题目如下:
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
<span style="font-size:14px;"> public boolean isPalindrome(ListNode head) { ArrayList<Integer> num_array = new ArrayList<Integer>(); while(head!=null){ num_array.add(head.val); head = head.next; } int i=0; int j=num_array.size()-1; while(j>=0 && i<=j){ if(num_array.get(i).intValue() != num_array.get(j).intValue()){ return false; } i++; j--; } return true; }</span>上面那种方法还是太LOW了一些,所以按例还是介绍评论区真正的高大上方法。这个方法的中心思想是将链表的前半段进行reverse操作,然后将reverse操作后的前半段链表和后半段链表节点的val值进行一一比对,如果所有节点的值都相同,说明原链表是“回文链表”,输出true即可,反之则输出false。难点有两个,一个是怎么找到原链表的中间节点,另一个就是链表的reverse操作。第一个问题可以通过新建一个移动速度是原指针两倍的指针,这样在这个指针移动到链表末尾的时候,原指针应该刚好移动到一半或者一半+1的位置,这和节点数的奇偶有关系。另一个问题其实没有什么好的解决方法,就是要通过新建三个指针,通过对改变这三个指针的位置关系来实现链表的reverse。等会可以通过分析一下具体的例子来观察这三个指针的作用,那先上代码。当然了,这些代码之前我都在LeetCode上跑过,肯定是可以Accepted的,代码如下:
<span style="font-size:14px;"> public boolean isPalindrome(ListNode head) { if(head == null) { return true; } ListNode p1 = head; ListNode p2 = head; ListNode p3 = p1.next; ListNode pre = p1; //find mid pointer, and reverse head half part while(p2.next != null && p2.next.next != null) { p2 = p2.next.next; pre = p1; p1 = p3; p3 = p3.next; p1.next = pre; } //odd number of elements, need left move p1 one step if(p2.next == null) { p1 = p1.next; } else { //even number of elements, do nothing } //compare from mid to head/tail while(p3 != null) { if(p1.val != p3.val) { return false; } p1 = p1.next; p3 = p3.next; } return true; }</span>其他的过程都不详细说了,单独举个例子分析一下reverse的过程。比如现在有一个链表1(N1)->2(N2)->3(N3)->2(N4)->1(N5),开始时p1指向的是N1位置,p3的位置是p1的next即N2位置,pre和p1都指向N1。
第一次循环:
将p1的值赋给pre,pre和p1都指向N1;
将p3的值赋给p1,这样p3和p1都指向N2,此时pre的next指向的也是N2;
将p3的next赋值给p3,这样p3的位置变成了N3,此时pre的next指向的也是N3,即N1的next变为了N3;
将p1的next赋值给pre,这样N1就变成了N2的next;
现在的链表变成了2(N2)->1(N1)->3(N3)->2(N4)->1(N5)。
第二次循环:
由于上一次循环过后,p1其实指向的就是N2位置,所以经过赋值后,pre也指向了N2位置;
然后将p3的值赋给p1,p1指向了N3位置;
将p3指向p3的next即N4,由于原来N1指向的是p3所对应的N3,但现在N3变成了N4,所以N1就自动指向N4了;
最后将p1的next指向pre,即把N3的next变成N1;
现在的链表变成了3(N3)->2(N2)->1(N1)->2(N4)->1(N5)。
之后的过程以此类推即可,难点主要是理解这种reverse方法。
0 0
- 关于LeetCode中Palindrome Linked List一题的理解
- 关于LeetCode中Linked List Cycle一题的理解
- 关于LeetCode中Remove Linked List Elements一题的理解
- 关于LeetCode中Palindrome Number一题的理解
- 关于LeetCode中Valid Palindrome一题的理解
- 【leetcode每日一题】234.Palindrome Linked List
- LeetCode Palindrome Linked List
- LeetCode - Palindrome Linked List
- leetcode: Palindrome Linked List
- Leetcode: Palindrome Linked List
- leetcode:Palindrome Linked List
- [LeetCode] Palindrome Linked List
- LeetCode || Palindrome Linked List
- 【leetcode】Palindrome Linked List
- LeetCode-Palindrome Linked List
- Leetcode|Palindrome Linked List
- [leetcode] Palindrome Linked List
- [LeetCode]Palindrome Linked List
- APICloud开发指南之$api
- CSS浮动(float,clear)通俗讲解
- As Fast As Possible
- TQ210——下载总结
- 【IOS开源项目】10个ios开发者必需要研究的swift开源项目
- 关于LeetCode中Palindrome Linked List一题的理解
- 一亿数据获取最大值的前100位
- 改变xcode代码区的背景颜色
- Android之禁止ViewPager滑动
- ctve facetest 链表删除save other list
- 堆排序
- 嵌入式学习--work5 RTC实时时钟学习
- CentOS安装vsftpd后不能新建文件夹的解决方法
- Java - 华为机试训练 - 明明的随机数