0234.回文链表

一次遍历

时间复杂度 $O(n)$,空间复杂度 $O(n)$。

在写该题目的 rust 解法时发现凭此时的代码水平只能借助数组辅助比较,具体代码见 rust tab。想要尽力实现类似其他语言一样在找到中间节点之后,反转后半部分链表的逻辑,但 rust 不可变性这一原则的存在限制了我的下一步工作。完美的解法让 copilot 来给我演示吧!

// Definition for singly-linked list.
// #[derive(PartialEq, Eq, Clone, Debug)]
// pub struct ListNode {
//   pub val: i32,
//   pub next: Option<Box<ListNode>>
// }
//
// impl ListNode {
//   #[inline]
//   fn new(val: i32) -> Self {
//     ListNode {
//       next: None,
//       val
//     }
//   }
// }
impl Solution {
    pub fn is_palindrome(head: Option<Box<ListNode>>) -> bool {
        // find middle
        let mut fast = &head;
        let mut slow = &head;
        let mut nums1 = vec![];
        while fast.is_some() && fast.as_ref().unwrap().next.is_some() {
            let nt = &fast.as_ref().unwrap().next;
            fast = &nt.as_ref().unwrap().next;
            nums1.push(slow.as_ref().unwrap().val);
            slow = &slow.as_ref().unwrap().next;
        }
        let mut nums2 = vec![];
        while slow.is_some() {
            nums2.push(slow.as_ref().unwrap().val);
            slow = &slow.as_ref().unwrap().next;
        }
        nums2.reverse();
        for i in 0..nums1.len() {
            if nums1[i] != nums2[i] {
                return false;
            }
        }
        true
    }
}
impl Solution {
    pub fn is_palindrome(head: Option<Box<ListNode>>) -> bool {
        let mut values = Vec::new();
        let mut current = head;
        while let Some(node) = current {
            values.push(node.val);
            current = node.next;
        }
        let mut left = 0;
        let mut right = values.len() - 1;
        while left < right {
            if values[left] != values[right] {
                return false;
            }
            left += 1;
            right -= 1;
        }
        true
    }
}

显然copilot 的代码(第二个rust tab)比我写的好看且简洁,但是空间复杂度并没有降低,仍旧需要调整。