43.Palindrome Linked List
2015-10-24 23:07
176 查看
Given a singly linked list, determine if it is a palindrome. Difficulty: Easy
Follow up:
Could you do it in O(n) time and O(1) space?
分析:思路是首先把链表分成前后两段(两段长度差0或1),然后转置其中的一段,再比较两个链表的值是否相等。
上面两个方法是我写的,思路是对的,但是看了网上写的一段代码之后,发现自己代码的规范性有待提高。
比如在我代码中
Follow up:
Could you do it in O(n) time and O(1) space?
分析:思路是首先把链表分成前后两段(两段长度差0或1),然后转置其中的一段,再比较两个链表的值是否相等。
/*方法一:转置前半段链表*/ public boolean isPalindrome(ListNode head) { ListNode p = head; ListNode q = head; int len = 0; /*Step1:先计算出链表的长度*/ while(p!=null){ len++; p=p.next; } if(len<=1){ return true;//如果链表是空的或者只有一个元素 } /*Step2:再让p指向head,并向前走len/2步*/ p = head; for(int i = 1;i<=len/2;i++){ p=p.next; }//出了for循环之后p指向链表最中间元素 System.out.println("p = "+p.val); /*Step3:转置head到p之前的节点,转置结束之后,l1为前半段转置之后的头结点*/ ListNode l1 = head; ListNode l2 = l1.next; l1.next = null; while(l2!=p){ ListNode l3= l2.next; l2.next = l1; l1 = l2; l2 = l3; }//转置结束之后,l1为前半段转置之后的头结点 System.out.println("l1 = "+l1.val); if(len%2 == 1){ p = p.next; } System.out.println("p = "+p.val); /*Step4:比较l1带领的前半段和p带领的后半段*/ while(l1!=null){ if(l1.val != p.val){ return false; } l1 = l1.next; p=p.next; } return true; }
/*方法二:转置的是后半段链表*/ public boolean isPalindrome2(ListNode head) { ListNode p = head; ListNode q = head; int len = 0; /*Step1:先计算出链表的长度*/ while(p!=null){ len++; p=p.next; } if(len<=1){ return true;//如果链表是空的或者只有一个元素 } /*Step2:再让p指向head,并向前走len/2步*/ p = head; for(int i = 1;i<=len/2;i++){ p=p.next; }//出了for循环之后p指向链表最中间元素 System.out.println("p = "+p.val); if(len%2 == 1){ p = p.next; } System.out.println("p = "+p.val); /*Step3:转置p为头结点的后半段*/ p = reverseList2(p); while(p!=null){ if(head.val != p.val){ return false; } head = head.next; p=p.next; } return true; } /*迭代做*/ public ListNode reverseList2(ListNode head) { if(head == null || head.next == null){ return head; }else{ ListNode l1 = head; ListNode l2 = l1.next; l1.next = null; while(l2.next != null){ ListNode l3 = l2.next; l2.next = l1; l1 = l2; l2 =l3; } l2.next = l1; return l2; } }
上面两个方法是我写的,思路是对的,但是看了网上写的一段代码之后,发现自己代码的规范性有待提高。
比如在我代码中
while(p!=null){ len++; p=p.next; } if(len<=1){ return true;//如果链表是空的或者只有一个元素 }可以修改为
if(head == null || head.next==null){ return true; }还有一个地方是我在代码中想要找到链表的中间元素p,遍历了1.5遍链表才得到,效率不好,但是下面这段代码巧妙的获得了链表中我想要的那个中间节点。1,2,3,4,5的话得到的是4.
private ListNode partition(ListNode head) { ListNode p = head; while(p.next!=null && p.next.next!=null) { p = p.next.next; head = head.next; } p = head.next; head.next = null; return p; }
相关文章推荐
- 脚本
- 在VS中自定义代码段
- 3D touch在Unity3D中的使用
- PHP7:10件事情你需要知道的
- 避免Time Machine备份Parallels Desktop的HDD虚拟硬盘文件
- leetcode之Validate Binary Search Tree
- 中项作业
- 模式识别导论大作业(k均值算法,感知器算法,fisher算法,贝叶斯决策,特征提取)
- Unity3D--学习太空射击游戏制作(四)
- PHP命名空间规则解析及高级功能3
- 51Nod 之贪心1
- 利用highchair画出简易版甘特图
- 韩剧中要熬制三天三夜的那碗汤——香浓牛骨汤
- 南阳理工--103背包问题
- 复习测试基础
- Android编码规范05
- python正则表达式
- Shell实现(四) 执行命令的实现(包含管道的实现)
- 关于如何在listview 中绑定结构体数组
- lintcode-赋值运算符重载