当前位置 博文首页 > tzh_linux的专栏:leetcode 234. 回文链表 golang实现
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
进阶:
你能否用O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
1. 利用快慢指针 找到链表的中间节点
2. 满指针在遍历的时候将前半部分的链表反转
3. p1 p2 分别指向中间节点开始遍历判断是否相等
1 -> 2 -> 2 -> 1 反转后 1 <- 2 2-> 1 p1=2 p2=2
1 -> 2 -> 0 -> 2 -> 1 反转后 1 <- 2 0->2->1 p1=2 p2 = 2
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func isPalindrome(head *ListNode) bool {
if head == nil || head.Next == nil{
return true
}
slow := head
fast := head.Next // 这里必须是从fast=head.Next 开始
var pre *ListNode
var prepre *ListNode
for fast != nil && fast.Next != nil{
prepre = pre
pre = slow
slow = slow.Next
fast = fast.Next.Next
pre.Next = prepre
}
// slow即为中间节点 此时 pre 和pre之间都已反转 slow还没有指向pre 因为我们还需要通过slow找到后面的节点
var p1 *ListNode
var p2 *ListNode
// 这里根据fast == nil 还是fast.Next == nil 可以判断链表节点是奇数还是偶数
if fast == nil{ // 奇数
p2 = slow.Next // 奇数个 则p2 为中间节点的Next
p1 = pre // p1 为中间节点的上一个
}else{ // fast.Next == nil 偶数个
p2 = slow.Next // p2 为中间节点slow的下一个
p1 = slow // p1 为slow
slow.Next = pre // 将slow节点指向slow的上一个节点
}
for p1 != nil{
if p1.Val != p2.Val{
return false
}
p1 = p1.Next
p2 = p2.Next
}
return true
}
cs