10.23 打卡
LeetCode每日一题 234.回文链表
这道题目的做法,其实跟10.20打卡的重排链表很类似,如果你做过那道题目的话,我相信对于这道题目,AC简直手到擒来~
方法一 数组+双指针
**思路:**拿到题目,我一开始想到的就是双指针,直接一个指针从头,一个指针从后,依次遍历往中间靠,这样不是简简单单吗?但是有一个问题就是链表的话,想要让指针知道链表的最后一个元素,这需要从头开始遍历,每一次都需要重复这个步骤,这很明显时间浪费就非常多了!所以我们就又想到了数组
,数组想访问任意一个元素都只需要知道下标而已,所以将链表中值复制到数组中,然后再来判断不就轻而易举吗?
下面直接给出代码
class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null)
return true;
ArrayList<ListNode> list = new ArrayList();
while(head != null){
list.add(head);
head = head.next;
}
int l = 0, r = list.size()-1;
while(l < r){
if(list.get(l).val != list.get(r).val)
return false;
l++;
r--;
}
return true;
}
}
复杂度分析:
时间复杂度: O(n),n为链表中元素的个数(复制到ArrayList中需要复制n次并且双指针判断时此时最差需要走O(n/2))
空间复杂度:O(n),n为链表中元素的个数,我们用到了一个ArrayList来储存链表中的元素
方法二:三步走(找中点,反转后部分链表,判断回文)
找中点
和反转链表
,在之前的题目们我们就已经找过了,这里不再浪费时间
下面直接贴出代码:
class Solution {
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null)
return true;
ListNode minNode = findMid(head);
ListNode head2 = reverseList(minNode.next);
//判断是否回文
ListNode p1 = head;
ListNode p2 = head2;
while( p2 != null){
if(p1.val != p2.val)
return false;
p1 = p1.next;
p2 = p2.next;
}
return true;
}
//翻转后部分的链表
public ListNode reverseList(ListNode head){
ListNode tail = null;
ListNode cur = head;
while(cur != null){
ListNode temp = cur.next;
cur.next = tail;
tail = cur;
cur = temp;
}
return tail;
}
//找中点
public ListNode findMid(ListNode head){
ListNode fast = head;
ListNode slow = head;
while(fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
}
复杂度分析:
时间复杂度:O(n),n 指的是链表的大小。
空间复杂度:O(1),只修改原本链表中节点的指向
方法三: 栈(该方法为逛LeetCode题解区觅得)
**思路:**巧妙了利用栈先进后出的性质,何谓回文?不就是正的看和反着看是一样的。所以将链表中的值先存进去栈中,然后再依次弹出和原来的链表进行比较,如果全部相等,则证明是回文链表,这种方法效率比较低,但是也不失为一种办法,简单粗暴(ps:所以我们还可以整个链表反转,然后再和原来的链表进行比较,哈哈哈好家伙=.=!)
下面直接贴出代码:
class Solution {
public boolean isPalindrome(ListNode head) {
if (head == null) {
return true;
}
if (head.next == null) {
return true;
}
//使用栈
Stack<Integer> stack = new Stack<>();
ListNode cur = head;
while (cur != null) {
stack.push(cur.val);
cur = cur.next;
}
while (head != null) {
if (head.val != stack.pop()) {
return false;
}
head = head.next;
}
return stack.isEmpty();
}
}