1、快慢指针:时间复杂度是O(n),空间复杂度是O(1)
思路:通过快慢指针找到中点,得到终点划分的A,B两段,将B段进行链表的反转,然后再和A段进行逐一比较;
注:快慢指针找中点的统一写法,这样写同是能找到B段的启始点的前一个位置,如果遇到需要断开A段与B段的关联的题目也可以直接用到
ListNode slow = head; //快指针 ListNode fast = head.next; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; } //以上的写法规律总结: //当是基数的时候,比如1,2,3,slow落在2上 //当偶数的时候,比如1,2 slow落在1上 slow=slow.next;
具体代码:
public boolean isPail (ListNode head) { if(head.next==null){ return true; } //慢指针 ListNode slow = head; //快指针 ListNode fast = head.next; while(fast!=null&&fast.next!=null){ fast=fast.next.next; slow=slow.next; } //以上的写法规律总结: //当是基数的时候,比如1,2,3,slow落在2上 //当偶数的时候,比如1,2 slow落在1上 //找到另一段的起点,本题这里不需要断开AB段的关联,因为在下面的while循环中 //判断条件是AB两段其中一段为null就退出循环,即使A还有指向B起点的连线也会 //退出循环,不过严谨地写出来也没问题 slow=slow.next; //进行链表的反转 ListNode res = reverse(slow); ListNode res2 = head; //逐一比较两段的数 while(res!=null&&res2!=null){ if(res.val!=res2.val){ return false; } res=res.next; res2=res2.next; } return true; } public ListNode reverse(ListNode node){ ListNode pre = null; while(node!=null){ ListNode temp = node.next; node.next = pre; pre=node; node=temp; } return pre; }