您的位置:首页 > 其它

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),然后转置其中的一段,再比较两个链表的值是否相等。

/*方法一:转置前半段链表*/
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: