Leetcode234. 回文链表
请判断一个链表是否为回文链表。
示例 1:
输入: 1->2
输出: false
示例 2:
输入: 1->2->2->1
输出: true
题解:
- 使用双指针,快指针走两步,慢指针走一步,当快指针走到最后时慢指针刚好走一半,找到中间点;
- 这样前半部分一个链表,后半部分为一个链表;
- 再对后半部分链表进行翻转;
- 对前半部分链表和翻转后的后半部分链表进行一一对比,如果有一个不相同,返回false,如果所有值都相同,则返回true
注意:
如果链表长度是偶数的话,前半部分和后半部分长度是一样的;
如果链表长度是奇数,那么前半部分的长度比后半部分长度多1个;
所以最后迭代链表的时候,以后半部分为准就可以了,当链表总长为奇数时,前半部分的最后一个节点就不会被遍历到了。
scala代码如下:
def isPalindrome(head: ListNode): Boolean = {
var result = true
if (head == null || head.next == null) {
result
} else {
val p = new ListNode(-1)
var fast = p
var slow = p
p.next = head
//慢指针走一步,快指针走两步,当快指针到达终点,慢指针刚好处于中间位置
while (fast != null && fast.next != null) {
slow = slow.next
fast = fast.next.next
}
//将快指针置于下半段链表中
fast = slow.next
//断开前后两个链表
slow.next = null
//慢指针置于上半段链表
slow = p.next
//翻转快链表
var pre: ListNode = null // 保存指针前一节点的信息,用于反转
while (fast != null) {
val nextTmp = fast.next
fast.next = pre
pre = fast
fast = nextTmp
}
//回文校验x
// 前后半链表逐一比较,当链表长度为奇数时前半段链表长度比后半段多1,所以以后半段为准
//将链表前半部分和反转的后半部分对比
while (pre != null && slow != null && result) {
if (slow.x != pre.x) {
result = false
}
pre = pre.next
slow = slow.next
}
result
}
}