LeetCodeAnimation/0234-isPalindrome/Article/0234-isPalindrome.md
2020-05-06 11:35:35 +08:00

111 lines
3.1 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## LeetCode第234号问题回文链表
> 本文首发于公众号图解面试算法 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
>
> 个人博客www.zhangxiaoshuai.fun
**本题选择leetcode第234题easy难度目前通过率41.5%**
```txt
题目描述
请判断一个链表是否为回文链表
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
```
***这道题还有进阶版本我们先实现这个普通版本再看***
### 题目分析
```
首先我们先遍历一遍链表将链表中的每个值存入数组当中然后我们判断数组中的元素是否满足回文数条件即可
这里因为我们不知道链表的长度我们先使用动态数组将值存起来然后再存到固定大小的数组中
```
### 解法一gif动画演示
![01](../Animation/solved01.gif)
### 代码
```java
public boolean isPalindrome(ListNode head) {
List<Integer> list = new ArrayList<>();
while (head != null) {
list.add(head.val);
head = head.next;
}
int[] arr = new int[list.toArray().length];
int temp = 0;
for (int a : list) {
arr[temp++] = a;
}
temp = 0;
for (int i = 0;i < arr.length/2;i++) {
if (arr[i] == arr[arr.length-i-1]) {
temp++;
}
}
if(temp == arr.length/2) return true;
return false;
}
```
**时间复杂度O(n) 空间复杂度O(n)**
### 进阶
**你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题**
**思路分析**我们先找到链表的中间结点然后将中间结点后面的链表进行反转反转之后再和前半部分链表进行比较如果相同则表示该链表属于回文链表返回true否则否则返回false
### 解法二gif动画演示
![02](../Animation/solved02.gif)
### 代码
```java
public boolean isPalindrome(ListNode head) {
if(head == null || head.next == null) return true;
ListNode p = new ListNode(-1);
ListNode low = p;
ListNode fast = p;
p.next = head;
//使用快慢指针来确定中间结点
while(fast != null && fast.next != null){
low = low.next;
fast = fast.next.next;
}
ListNode cur = low.next;
ListNode pre = null;
low.next = null;
low = p.next;
//反转后半部分链表
while(cur != null){
ListNode tmp = cur.next;
cur.next = pre;
pre = cur;
cur = tmp;
}
//将前半部分链表和后半部分进行比较
while(pre != null){
if(low.val != pre.val){
return false;
}
low = low.next;
pre = pre.next;
}
return true;
}
```
**时间复杂度O(n) 空间复杂度O(1)**
**没错可以看到上面的代码是完全能可以通过的虽然我们完成了题目但是我们改变了链表的结构也就是说它现在不是它了出题人应该是不希望我们破坏链表的所以在我们完成判断之后需要将链表恢复原样也就是将后半部分链表反转之后接到前半部分链表的末尾**