题目:
Given a singly linked list, determine if it is a palindrome.
Follow up:
Could you do it in O(n) time and O(1) space?
题解:
判断一个链表是不是回文的,这里要求O(n)时间复杂度和O(1)的空间时间复杂度,总共想了三种办法,三种办法都用到了两个指针,符合题目要求的只有最后一种。
第一种办法:用数组倒着存前半段的链表的值,然后和后半段链表的值进行比较。这种解法运行的时间最久可能是因为数组倒着插入比较耗时。
代码:
//用数组实现 o(n/2)空间 public static boolean isPalindrome(ListNode head) { // ArrayList<Integer> nodeVal=new ArrayList<>(); LinkedList<Integer> nodeVal=new LinkedList<>(); if(head==null||head.next==null) return true; ListNode slow=head; ListNode fast=head; nodeVal.add(0,slow.val); while(fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; nodeVal.add(0,slow.val); } ListNode cur=slow; if(fast.next!=null)//链表长度为偶数 cur=slow.next; int i=0; while(cur!=null) { if(nodeVal.get(i)!=cur.val) return false; cur=cur.next; i++; } return true; }
第二种解法:在第一种的思路的基础上,我们要实现一个倒序,我们干嘛不用现成的数据结构-栈,于是把链表前半段压栈,然后出栈和后面的链表依次比较,这种运行时间最短,但因为用到了栈还是不符合题目要求。
代码:
//用栈实现 public static boolean isPalindrome2(ListNode head) { Stack<ListNode> stack=new Stack<>(); ListNode slow=head; ListNode fast=head; if(fast==null||fast.next==null)//0个节点或是1个节点 return true; stack.push(slow); while(fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; stack.push(slow); } if(fast.next!=null)//链表长度为偶数 slow=slow.next; ListNode cur=slow; while(cur!=null) { if(cur.val!=stack.pop().val) return false; cur=cur.next; } return true; }
第三种:我们这样想,我们可不可以不借助外在的存储实现倒序呢,其实是可以的,链表反转的时候我们就没有借助外在存储。思路是把后半段的原地链表反转然后和前半段进行比较(当然你也可以反转前半段)运行时间稍微比第二种慢一些,但是符合题目O(1)空间复杂度的要求
代码:
//链表原地转置实现o(1)空间复杂度 public static boolean isPalindrome3(ListNode head) { ListNode slow=head; ListNode fast=head; if(fast==null||fast.next==null)//0个节点或是1个节点 return true; while(fast.next!=null&&fast.next.next!=null) { fast=fast.next.next; slow=slow.next; } //对链表后半段进行反转 ListNode midNode=slow; ListNode firNode=slow.next;//后半段链表的第一个节点 ListNode cur=firNode.next;//插入节点从第一个节点后面一个开始 firNode.next=null;//第一个节点最后会变最后一个节点 while(cur!=null) { ListNode nextNode=cur.next;//保存下次遍历的节点 cur.next=midNode.next; midNode.next=cur; cur=nextNode; } //反转之后对前后半段进行比较 slow=head; fast=midNode.next; while(fast!=null) { if(fast.val!=slow.val) return false; slow=slow.next; fast=fast.next; } return true; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-22 15:52:44