请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
题解:
思路一:
- 利用快慢指针找到中间节点,并将中间节点之前的元素入栈
- 然后遍历中间节点之后的元素
- 如果与栈顶一致, 则栈pop(). 遍历下一个
- 如果与栈顶不一致, 则 return false
- 遍历完链表, 一直一样, 且最后 栈空。 return ture
代码如下;
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
|
// 使用栈
public static boolean isPalindrome(ListNode head) {
if (head == null || head.next == null) return true;
Stack <Integer>s = new Stack();
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null){
s.push(slow.val);
slow = slow.next;
fast = fast.next.next;
}
if (fast != null) slow = slow.next;
while (slow != null){
int val = s.pop();
if (val != slow.val) return false;
slow = slow.next;
}
return s.isEmpty();
}
|
时间复杂度 : O(N) 遍历整遍链表,N为链表中元素的个数
空间复杂度 : O(N) 使用了额外的栈存储空间
思路二;
- 使用数组
- 遍历将链表中所有元素都加入数组
- 定义两个指针 begain 和 end,分别指向链表的开头和结尾
- 比较,begain 和 end 指向元素一样是, begain ++, end – 继续比较
- 不一样时,return false
- 遍历到最后,一直一样。 则为回文。 return true.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// 使用数组
public static boolean isPalindrome1(ListNode head) {
ArrayList list = new ArrayList();
while (head != null){
list.add(head.val);
head = head.next;
}
System.out.println(list);
int begain = 0;
int end = list.size() - 1;
while (begain <= end){
if (!list.get(begain).equals(list.get(end))) return false;
begain ++;
end --;
}
return true;
}
|
时间复杂度 : O(N) 遍历整遍链表,N为链表中元素的个数
空间复杂度 : O(N) 使用了额外的栈存储空间
思路三:
- 先找到链表的中间节点middle
- 反转middle
- 从头到位比较 head 和 反转后的mid
- 如果不一致, 则返回 false
- 如果一致,继续向下遍历
- 遍历到末尾,一致是一样, 则为回文
代码如下:
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
|
public static boolean isPalindrome(ListNode head){
ListNode middel = middle(head);
ListNode revertHead = revert(middel);
while (revertHead != null){
if (revertHead.val != head.val) return false;
head = head.next;
revertHead = revertHead.next;
}
return true;
}
public static ListNode middle(ListNode head){
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
if (fast != null) slow = slow.next;
return slow;
}
public static ListNode revert(ListNode node){
ListNode newHead = null;
while (node != null){
ListNode tmp = node.next;
node.next = newHead;
newHead = node;
node = tmp;
}
return newHead;
}
|
时间复杂度 : O(N) 遍历整遍链表,N为链表中元素的个数
空间复杂度 : O(1) 没有使用额外的栈存储空间