题目描述
编写一个函数,检查输入的链表是否是回文的。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
解法
方法一:快慢指针 + 反转链表
我们首先判断链表是否为空,如果为空,直接返回 true
。
接下来,我们使用快慢指针找到链表的中点,如果链表长度为奇数,那么慢指针指向的就是中点,如果链表长度为偶数,那么慢指针指向的是中间两个节点的前一个节点。
然后,我们将慢指针之后的链表反转,这样我们就得到了链表的后半部分,其中链表头节点为 \(p\) 。
最后,我们循环比较链表的前半部分和后半部分,如果有不相等的节点,直接返回 false
,否则遍历完链表后返回 true
。
时间复杂度 \(O(n)\) ,其中 \(n\) 为链表的长度。空间复杂度 \(O(1)\) 。
Python3 Java C++ Go TypeScript JavaScript C# Swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 # Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution :
def isPalindrome ( self , head : ListNode ) -> bool :
if head is None :
return True
slow , fast = head , head . next
while fast and fast . next :
slow = slow . next
fast = fast . next . next
p = slow . next
slow . next = None
dummy = ListNode ()
while p :
next = p . next
p . next = dummy . next
dummy . next = p
p = next
p = dummy . next
while p :
if head . val != p . val :
return False
head = head . next
p = p . next
return True
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 /**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isPalindrome ( ListNode head ) {
if ( head == null ) {
return true ;
}
ListNode slow = head ;
ListNode fast = head . next ;
while ( fast != null && fast . next != null ) {
slow = slow . next ;
fast = fast . next . next ;
}
ListNode p = slow . next ;
slow . next = null ;
ListNode dummy = new ListNode ( 0 );
while ( p != null ) {
ListNode next = p . next ;
p . next = dummy . next ;
dummy . next = p ;
p = next ;
}
p = dummy . next ;
while ( p != null ) {
if ( head . val != p . val ) {
return false ;
}
head = head . next ;
p = p . next ;
}
return true ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 /**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public :
bool isPalindrome ( ListNode * head ) {
if ( ! head ) {
return true ;
}
ListNode * slow = head ;
ListNode * fast = head -> next ;
while ( fast && fast -> next ) {
slow = slow -> next ;
fast = fast -> next -> next ;
}
ListNode * p = slow -> next ;
slow -> next = nullptr ;
ListNode * dummy = new ListNode ( 0 );
while ( p ) {
ListNode * next = p -> next ;
p -> next = dummy -> next ;
dummy -> next = p ;
p = next ;
}
p = dummy -> next ;
while ( p ) {
if ( head -> val != p -> val ) {
return false ;
}
head = head -> next ;
p = p -> next ;
}
return true ;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 /**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func isPalindrome ( head * ListNode ) bool {
if head == nil {
return true
}
slow , fast := head , head . Next
for fast != nil && fast . Next != nil {
slow , fast = slow . Next , fast . Next . Next
}
p := slow . Next
slow . Next = nil
dummy := & ListNode {}
for p != nil {
next := p . Next
p . Next = dummy . Next
dummy . Next = p
p = next
}
p = dummy . Next
for p != nil {
if head . Val != p . Val {
return false
}
head = head . Next
p = p . Next
}
return true
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 /**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
* }
*/
function isPalindrome ( head : ListNode | null ) : boolean {
if ( ! head ) {
return true ;
}
let slow = head ;
let fast = head . next ;
while ( fast && fast . next ) {
slow = slow . next ;
fast = fast . next . next ;
}
let p = slow . next ;
slow . next = null ;
const dummy = new ListNode ( 0 );
while ( p ) {
const next = p . next ;
p . next = dummy . next ;
dummy . next = p ;
p = next ;
}
p = dummy . next ;
while ( p ) {
if ( head . val !== p . val ) {
return false ;
}
head = head . next ;
p = p . next ;
}
return true ;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 /**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var isPalindrome = function ( head ) {
if ( ! head ) {
return true ;
}
let slow = head ;
let fast = head . next ;
while ( fast && fast . next ) {
slow = slow . next ;
fast = fast . next . next ;
}
let p = slow . next ;
slow . next = null ;
const dummy = new ListNode ( 0 );
while ( p ) {
const next = p . next ;
p . next = dummy . next ;
dummy . next = p ;
p = next ;
}
p = dummy . next ;
while ( p ) {
if ( head . val !== p . val ) {
return false ;
}
head = head . next ;
p = p . next ;
}
return true ;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 /**
* Definition for singly-linked list.
* public class ListNode {
* public int val;
* public ListNode next;
* public ListNode(int x) { val = x; }
* }
*/
public class Solution {
public bool IsPalindrome ( ListNode head ) {
if ( head == null ) {
return true ;
}
ListNode slow = head ;
ListNode fast = head . next ;
while ( fast != null && fast . next != null ) {
slow = slow . next ;
fast = fast . next . next ;
}
ListNode p = slow . next ;
slow . next = null ;
ListNode dummy = new ListNode ( 0 );
while ( p != null ) {
ListNode next = p . next ;
p . next = dummy . next ;
dummy . next = p ;
p = next ;
}
p = dummy . next ;
while ( p != null ) {
if ( head . val != p . val ) {
return false ;
}
head = head . next ;
p = p . next ;
}
return true ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 /**
* public class ListNode {
* var val: Int
* var next: ListNode?
* init(_ x: Int) {
* self.val = x
* self.next = nil
* }
* }
*/
class Solution {
func isPalindrome ( _ head : ListNode ?) -> Bool {
if head == nil {
return true
}
var slow = head
var fast = head ?. next
while fast != nil && fast ?. next != nil {
slow = slow ?. next
fast = fast ?. next ?. next
}
var p = slow ?. next
slow ?. next = nil
var dummy = ListNode ( 0 )
while p != nil {
let next = p ?. next
p ?. next = dummy . next
dummy . next = p
p = next
}
p = dummy . next
var currentHead = head
while p != nil {
if currentHead ?. val != p ?. val {
return false
}
currentHead = currentHead ?. next
p = p ?. next
}
return true
}
}