题目
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
思路
- 创建一个数据或者栈来存储链表中的所有值,通过首尾的匹配来判断是否回文
- 将链表一分为2,将其中一个反转,遍历是否相等
java
创建栈、数组、不满足空间复杂度为O(1)
// 数组
class Solution {
public boolean isPalindrome(ListNode head) {
List<Integer> list = new ArrayList();
while(head != null)
{
list.add(head.val);
head = head.next;
}
for (int i = 0;i < list.size();i ++)
{
if (!list.get(i).equals(list.get(list.size() - i - 1)))
{
return false;
}
}
return true;
}
}
// 栈
class Solution {
public boolean isPalindrome(ListNode head) {
ListNode p = head;
Stack<Integer> s = new Stack();
while(p!=null){
s.push(p.val);
p=p.next;
}
while(!s.empty()){
if(head.val!=s.pop()){
return false;
}
head=head.next;
}
return true;
}
}
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome(ListNode head) {
// 先找到中间节点,然后反转前一部分,之后两段链表进行比较
// 1.找到中间节点,一个快,一个慢
ListNode fast = head;
ListNode slow = head;
if (fast == null || fast.next == null) {// 如果没有元素或只有一个元素,就直接返回true
return true;
}
while (fast.next != null && fast.next.next != null) {// 找到第(n+1)/2的指针位置,n为元素的个数,比如有3个元素,那么
fast = fast.next.next; // slow就在2这个位置,如果为4,还是在2这个位置,
slow = slow.next; // 因为回文是121,1221,需要考虑奇数位还是偶数位
}
int flag = 0;// 标志位,判断链表是奇数位还是偶数位,为1说明是奇数位
if (fast.next == null) {
flag = 1;
}
ListNode head2 = slow.next;// 第二段链表的开头指针
// 反转链表
ListNode pre = null;
ListNode now = head;
ListNode next = head;
while (next != head2) {
next = now.next;
now.next = pre;
pre = now;
now = next;
}
if (flag == 1) {// 如果是奇数位像121,中间的2不参与判断,就像原来是1->2->1,反转之后一段位2->1,,另一段是1,
pre = pre.next;
}
while (head2 != null) {
if (head2.val != pre.val) {
return false;
}
head2 = head2.next;
pre = pre.next;
}
return true;
}
}