leetcode之234回文链表Golang
所以在本题,我们采用的思路就是将链表的后面半部分反转,然后再比较前面半部分和后面半部分是否相同
首先我们需要找到后面半部分,采用的方法是双指针的思路,快指针每次向后面走两步,慢指针每次向后面走一步,当快指针走到链表最后的时候,慢指针刚好走了一半,具体如下:
-
首先如果链表是一个空链表或者链表只有一个结点,那么就直接判断这个链表就是回文链表
-
然后将慢指针置于第一个结点,快指针置于第二个结点
-
当链表为
1 2 3 4时,当快指针指向4时候慢指针指向2 -
当链表为
1 2 3 4 5时,我们需要注意的是,因为每次快指针向后走两步,但是如果快指针走第一步的时候就到了链表末尾,那么此时快指针就走一步而慢指针不需要移动,所以此时当快指针指向5的时候,慢指针指向了2
-
-
然后从慢指针的下一个结点开始反转链表
-
此时就可以从原本的链表末尾向前遍历半个链表了,然后将第一个元素与最后一个元素比较,第二个元素与倒数第二个元素比较。。。
-
如果中间出现了不相等的元素,那么就直接返回
false,如果整个链表的元素都比较完了,那么就返回true
代码如下
func isPalindrome(head *ListNode) bool {
// 只有一个结点或者没有结点都是回文链表
if head == nil || head.Next == nil {
return true
}
fast, slow := head.Next, head
for fast != nil {
if fast.Next == nil {
break
}
fast = fast.Next
if fast.Next == nil {
break
}
fast = fast.Next
slow = slow.Next
}
// 反转后面半部分的链表
pre := slow.Next
cur := pre.Next
for cur != nil {
cur.Next, pre, cur = pre, cur, cur.Next
}
reverse := pre
for head != slow.Next {
if head.Val == reverse.Val {
head, reverse = head.Next, reverse.Next
} else {
return false
}
}
return true
}
浙公网安备 33010602011771号