回文链表
题目
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思路
- 最简单的思路是使用字符串或集合收集后比对.但是因为存在负数,所以使用字符串的方式会不方便,因此最简单的方式使用集合.
- 还可以使用栈来充当空间
- O(n)的时间复杂度和O(1)的空间复杂度的方法:先使用快慢节点找出链表中点,然后将后半段链表翻转,比较两个链表是否相等即可.
代码
- 使用集合
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
ArrayList<Integer> list = new ArrayList();
while(head != null){
list.add(head.val);
head = head.next;
}
for(int i = 0;i < list.size()/2;i++){
if(!list.get(i).equals(list.get(list.size()-1-i))){
return false;
}
}
return true;
}
}
- 使用快慢指针找到中点,然后饭后之后的链表,将之前和之后的进行对比.
class Solution {
public boolean isPalindrome(ListNode head) {
// 要实现 O(n) 的时间复杂度和 O(1) 的空间复杂度,需要翻转后半部分
if (head == null || head.next == null) {
return true;
}
ListNode fast = head;
ListNode slow = head;
// 根据快慢指针,找到链表的中点
while(fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
slow = reverse(slow.next);
while(slow != null) {
if (head.val != slow.val) {
return false;
}
head = head.next;
slow = slow.next;
}
return true;
}
private ListNode reverse(ListNode head){
// 递归到最后一个节点,返回新的新的头结点
if (head.next == null) {
return head;
}
ListNode newHead = reverse(head.next);
head.next.next = head;
head.next = null;
return newHead;
}
}