法一:栈 时间O(n)+空间O(n) public static boolean ispanlindrome(Node head){ if(head==null||head.next==null)return true; Node first=head;//快指针 Node second=head;//慢指针 while(first.next!=null&&first.next.next!=null){//找到中间的元素 first=first.next.next; //1,2,3,2,1:3 second=second.next; //1,2,2,1:第二个2 } second=second.next; //second指向后半部分第一个元素
Stack<Node> stack=new Stack<Node>(); while(second!=null){ //后半部分入栈 stack.push(second); second=second.next; }
while(!stack.isEmpty()){ //出栈匹配 if(stack.pop().val!=head.val){ return false; }else{ head=head.next; } } return true; } 法二:栈+逆序 时间O(n)+空间O(1) public static boolean isplrome(Node head){ boolean res=true; //暂存返回结果 if(head==null||head.next==null)return res; Node first=head; //快指针 Node second=head; //慢指针 while(first.next!=null&&first.next.next!=null){ //找到中间的元素 first=first.next.next; //1,2,3,2,1:3 second=second.next; //1,2,2,1:第二个2 } Node pre=reverse(second); //逆序后半部分 Node last=pre; //记录要恢复链表的后半部分头部 while(pre!=head){ //匹配 if(pre.val!=head.val){ res=false; break; }else{ pre=pre.next; head=head.next; } } Node p=reverse(last);//恢复链表 return res; } public static Node reverse(Node prenode){ Node pre=prenode; Node cur=pre.next; pre.next=null; //把中间next指针设置为空 Node next=null; while(cur!=null){ next=cur.next; cur.next=pre; pre=cur; cur=next; } return pre; }