leetcode-234-回文链表(palindrome linked list)-java

题目及案例

package pid234;
/*回文链表

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

输入: 1->2->2->1
输出: true

进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

*/


import pid234.LinkList;
import pid234.LinkList.ListNode;

public class main {
	
	
	public static void main(String[] args) {
		
		LinkList a=new LinkList(1);
		a.addLast(2);
		a.addLast(5);
		a.printList();
		test(a.first);
		
		LinkList b=new LinkList(-5);
		b.addLast(0);
		b.addLast(-5);
		b.printList();
		test(b.first);		
		
		LinkList c=new LinkList(1);
		c.addLast(2);
		c.addLast(2);
		c.addLast(1);
		c.printList();
		test(c.first);
		
		/*LinkList c=new LinkList(1);
		c.addLast(2);
		c.addLast(500);
		LinkList d=new LinkList(1);
		d.addLast(2);
		d.addLast(3);
		
		c.printList();		
		d.printList();
		test(c.first,d.first);*/
	}
		 
	private static void test(ListNode ito) {
		Solution solution = new Solution();
		Boolean rtn;
		long begin = System.currentTimeMillis();
		System.out.println();
		//开始时打印数组
		
		rtn=solution.isPalindrome(ito);//执行程序
		long end = System.currentTimeMillis();	
		
		System.out.println(rtn);
		
		//System.out.println(":rtn" );
		//System.out.print(rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

linkedlist

package pid234;


public class LinkList {
	public class ListNode {
  	  public int val;
  	  public ListNode next;
  	  ListNode(int x) 
  	  { val = x; 
  	  	next=null;
  	  }
  	  public ListNode() {
  		  val=0;
  		  next=null;
  	  }
  	  
  	  public void printNodeToEnd(){
  		ListNode a=this;
		System.out.println("print node to end");
		while(a!=null){//直到最后一个不为空的节点
			System.out.print(a.val+"  ");
			a=a.next;
		}
		System.out.println();
  	  }
	}
	
	ListNode first;
	
	public LinkList(int x){
		first=new ListNode(x);
		first.next=null;
	}
	public LinkList(){
		first=null;
		first.next=null;
	}
	
	public void addLast(int x){
		
		if(first==null){
			first=new ListNode(x);
			return;
		}
		ListNode a=first;
		while(a.next!=null){
			a=a.next;
		}
		ListNode b=new ListNode(x);
		a.next=b;
	}
	
	public void printList(){
		ListNode a=first;
		System.out.println("print listnode");
		while(a!=null){//直到最后一个不为空的节点
			System.out.print(a.val+"  ");
			a=a.next;
		}
		System.out.println();
	}
	
	
	
}

解法1(成功,速度快,3ms)
速度o(n) 空间o(n)
将链表扫描加入arraylist,在头尾比较

package pid234;


import java.util.ArrayList;
import java.util.List;

import pid234.LinkList;
import pid234.LinkList.*;
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        List<ListNode> a=new ArrayList<ListNode>();
    	if(head==null){
    		return true;
    	}
    	ListNode x=head;
    	while(x!=null){
    		a.add(x);
    		x=x.next;
    	}
    	int length=a.size();
    	if(length==1){
    		return true;
    	}
    	int i=0;
    	while(i<length/2+1){
    		if(a.get(i).val!=a.get(length-i-1).val){
    			return false;
    		}
    		i++;
    	}
    	return true;
    }
}

解法2(成功,2ms,极快)
速度o(n) 空间o(1)
先扫描得到长度,再将前一半反转
再比较两条链表

	public boolean isPalindrome(ListNode head) {
        if(head==null||head.next==null){
        	return true;
        }
        //先计算出有几个节点
        int length=0;
        ListNode now=head;
        while(now!=null){
        	now=now.next;
        	length++;
        }
        //再将中间前一半的节点反转
        int midLength=length/2;
        ListNode pre=head;
        ListNode next=head.next;
        now=head.next;
        for(int i=1;i<midLength;i++){
        	next=now.next;
	    	now.next=pre;
	    	pre=now;
	    	now=next;
        }
        //双指针检查是否回文
        ListNode l1;
        if(midLength==1){
        	l1=head;
        }
        else{
        	l1=pre;
        }
        ListNode l2;
        if(length%2==0){
        	l2=next;
        }
        else{
        	l2=next.next;
        }
        while(l2!=null){
        	if(l1.val==l2.val){
        		l1=l1.next;
        		l2=l2.next;
        	}
        	else{
        		return false;
        	}
        }
		return true;
    }

解法3(别人的)
在循环的时候,使用快慢指针得到中点,而且慢指针同时将链表反转。最后比较两个链表

public boolean isPalindrome(ListNode head) {
    	if(head == null || head.next == null) return true;
    	ListNode slow = head, fast = head.next, pre = null, prepre = null;
    	while(fast != null && fast.next != null) {
    		//反转前半段链表
    		pre = slow;
    		slow = slow.next;
    		fast = fast.next.next;
    		//先移动指针再来反转
    		pre.next = prepre;
    		prepre = pre;
    	}
    	ListNode p2 = slow.next;
    	slow.next = pre;
    	ListNode p1 = fast == null? slow.next : slow;
    	while(p1 != null) {
    		if(p1.val != p2.val)
    			return false;
    		p1 = p1.next;
    		p2 = p2.next;
    	}
		return true;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值