回文链表的判断

来源:互联网 发布:文言中乎的用法和意义 编辑:程序博客网 时间:2024/05/24 01:26

题目:

如 1->2->3->2->1是回文,1->2->3->1不是

思路:

1.时间复杂度O(n),n个额外空间

使用栈Stack,将链表节点从头至尾入栈。然后栈顶和链表元素依次比对,如果节点相同则是回文的。

 

public class Palindrome {    public boolean isPalindrome(ListNode pHead) {        // write code here        if(pHead==null) return false;        if(pHead.next==null) return true;        ListNode head=pHead;        Stack<Integer> stack=new Stack();        while(head!=null){            stack.push(head.val);            head=head.next;        }        head=pHead;        while(head!=null){            if(stack.pop()!=head.val) return false;            head=head.next;        }        return true;    }}


2.时间复杂度O(n),n/2个额外空间

使用栈Stack,快慢指针,快指针一次走两步,慢指针一次一步。将慢指针走过的节点入栈。当快指针走到尾节点,慢指针来到中间,如果链表总长度是奇数,那么中间节点不如栈,否则入栈。然后慢指针开始走后半部分,依次弹出栈顶与其比对。

 

public class Palindrome {    public boolean isPalindrome(ListNode pHead) {        // write code here        if(pHead==null) return false;        if(pHead.next==null) return true;        ListNode quick=pHead;        ListNode slow=pHead;        Stack<Integer> stack=new Stack();        int count=0;        while(quick!=null){//快指针每次走两步,慢指针走一步                        if(count%2==0){//当快指针走了两步时,慢指针走一步                stack.push(slow.val);            slow=slow.next;            }            count++;quick=quick.next;        }                if(count%2==1) stack.pop();//判断中间位置,是否该入栈        while(slow!=null){            if(stack.pop()!=slow.val) return false;            slow=slow.next;        }        return true;    }}

3.时间复杂度O(n),空间O(1)

首先利用快慢指针,找到链表的中间节点3和尾节点2. 然后将右半部分逆序,变成

1->2->3<-2<-1这种形式。从两边向中间进行比对。当然比对结束后,要将逆序的链表恢复,变成1->2->3->2->1


public class Palindrome {public boolean isPalindrome(ListNode head) {if (head == null || head.next == null) {return true;}ListNode n1 = head;ListNode n2 = head;while (n2.next != null && n2.next.next != null) { // find mid noden1 = n1.next; // n1 -> midn2 = n2.next.next; // n2 -> end}n2 = n1.next; // n2 -> right part first noden1.next = null; // mid.next -> nullListNode n3 = null;while (n2 != null) { // right part convertn3 = n2.next; // n3 -> save next noden2.next = n1; // next of right node convertn1 = n2; // n1 moven2 = n3; // n2 move}n3 = n1; // n3 -> save last noden2 = head;// n2 -> left first nodeboolean res = true;while (n1 != null && n2 != null) { // check palindromeif (n1.val != n2.val) {res = false;break;}n1 = n1.next; // left to midn2 = n2.next; // right to mid}n1 = n3.next;n3.next = null;while (n1 != null) { // recover listn2 = n1.next;n1.next = n3;n3 = n1;n1 = n2;}return res;}}