Skip to content

Commit c92c064

Browse files
authored
Merge pull request MisterBooo#73 from xiaoshuai96/master
solved @xiaoshuai96
2 parents a1a7ffa + 6ba30cd commit c92c064

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed
2.94 MB
Loading
3.14 MB
Loading
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
> 本文首发于公众号「图解面试算法」,是 [图解 LeetCode ](<https://github.com/MisterBooo/LeetCodeAnimation>) 系列文章之一。
2+
>
3+
> 个人博客:https://www.zhangxiaoshuai.fun
4+
5+
**本题选择leetcode第234题,easy难度,目前通过率41.5%**
6+
7+
```txt
8+
题目描述:
9+
请判断一个链表是否为回文链表。
10+
示例 1:
11+
输入: 1->2
12+
输出: false
13+
14+
示例 2:
15+
输入: 1->2->2->1
16+
输出: true
17+
```
18+
19+
***这道题还有进阶版本,我们先实现这个普通版本再看。***
20+
21+
### 题目分析:
22+
23+
```
24+
首先,我们先遍历一遍链表,将链表中的每个值存入数组当中,然后我们判断数组中的元素是否满足回文数条件即可。
25+
这里因为我们不知道链表的长度,我们先使用动态数组将值存起来,然后再存到固定大小的数组中。
26+
```
27+
28+
### 解法一gif动画演示:
29+
30+
![01](../Animation/solved01.gif)
31+
32+
### 代码:
33+
34+
```java
35+
public boolean isPalindrome(ListNode head) {
36+
List<Integer> list = new ArrayList<>();
37+
while (head != null) {
38+
list.add(head.val);
39+
head = head.next;
40+
}
41+
int[] arr = new int[list.toArray().length];
42+
int temp = 0;
43+
for (int a : list) {
44+
arr[temp++] = a;
45+
}
46+
temp = 0;
47+
for (int i = 0;i < arr.length/2;i++) {
48+
if (arr[i] == arr[arr.length-i-1]) {
49+
temp++;
50+
}
51+
}
52+
if(temp == arr.length/2) return true;
53+
return false;
54+
}
55+
```
56+
57+
**时间复杂度:O(n) 空间复杂度:O(n)**
58+
59+
### 进阶:
60+
61+
**你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?**
62+
63+
**思路分析:**我们先找到链表的中间结点,然后将中间结点后面的链表进行反转,反转之后再和前半部分链表进行比较,如果相同则表示该链表属于回文链表,返回true;否则,否则返回false
64+
65+
### 解法二gif动画演示:
66+
67+
![02](../Animation/solved02.gif)
68+
69+
### 代码:
70+
71+
```java
72+
public boolean isPalindrome(ListNode head) {
73+
if(head == null || head.next == null) return true;
74+
ListNode p = new ListNode(-1);
75+
ListNode low = p;
76+
ListNode fast = p;
77+
p.next = head;
78+
//使用快慢指针来确定中间结点
79+
while(fast != null && fast.next != null){
80+
low = low.next;
81+
fast = fast.next.next;
82+
}
83+
ListNode cur = low.next;
84+
ListNode pre = null;
85+
low.next = null;
86+
low = p.next;
87+
88+
//反转后半部分链表
89+
while(cur != null){
90+
ListNode tmp = cur.next;
91+
cur.next = pre;
92+
pre = cur;
93+
cur = tmp;
94+
}
95+
//将前半部分链表和后半部分进行比较
96+
while(pre != null){
97+
if(low.val != pre.val){
98+
return false;
99+
}
100+
low = low.next;
101+
pre = pre.next;
102+
}
103+
return true;
104+
}
105+
```
106+
107+
**时间复杂度:O(n) 空间复杂度:O(1)**
108+
109+
**没错,可以看到上面的代码是完全能可以通过的,虽然我们完成了题目,但是我们改变了链表的结构,也就是说它现在不是它了;出题人应该是不希望我们破坏链表的,所以在我们完成判断之后,需要将链表恢复原样,也就是将后半部分链表反转之后接到前半部分链表的末尾。**

0 commit comments

Comments
 (0)