ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

千问 LeetCode 24.两两交换链表中的节点 Rust实现

千问    LeetCode 24.两两交换链表中的节点 Rust实现 LeetCode 24 两两交换链表中的节点在 Rust 中实现的核心难点在于所有权与借用检查必须频繁使用 Option::take() 转移节点所有权来操作指针。以下提供两种主流解法解法一迭代法虚拟头节点 take这是最经典的写法思路与 C/Java 一致通过 take() 解决所有权问题。impl Solution {pub fn swap_pairs(head: OptionBox) - OptionBox {let mut dummy Box::new(ListNode { val: 0, next: head });let mut cur mut dummy;while let Some(mut node1) cur.next.take() { // 如果只有一个节点无法配对直接放回并退出 let Some(mut node2) node1.next.take() else { cur.next Some(node1); break; }; // 暂存下一轮的起始节点 let node3 node2.next.take(); // 执行交换node1 - node3, node2 - node1 node1.next node3; node2.next Some(node1); cur.next Some(node2); // cur 前进两步到达下一组待交换节点的前一个位置 cur cur.next.as_mut().unwrap().next.as_mut().unwrap(); } dummy.next }}执行流程以 [1,2,3,4] 为例初始dummy - 1 - 2 - 3 - 4第一轮交换take() 取出 node11, node22, node33-4重连node1.next 3-4, node2.next 1dummy - 2 - 1 - 3 - 4cur 前进到 node1(值为1)的位置第二轮交换take() 取出 node13, node24, node3None重连node1.next None, node2.next 3dummy - 2 - 1 - 4 - 3返回 dummy.next [2,1,4,3] ✅解法二直接操作引用无需虚拟头节点这种写法更简洁直接对 head 的可变引用进行操作省去了虚拟头节点。impl Solution {pub fn swap_pairs(mut head: OptionBox) - OptionBox {let mut current mut head;loop { match current { None break, Some(current_node) { match current_node.next.take() { None break, Some(mut next_node) { // 重新连接指针 current_node.next next_node.next.take(); next_node.next current.take(); *current Some(next_node); // 前进两步 current mut current.as_mut() .unwrap().next.as_mut() .unwrap().next; } } } } } head }}两种解法对比维度 解法一虚拟头节点 解法二直接引用代码量 稍多 更简洁可读性 逻辑清晰易于理解 需要理解 take() 引用的配合时间复杂度 O(n) O(n)空间复杂度 O(1) O(1)Rust 链表题的关键技巧Option::take()将 Option 中的值取出原位留下 None。这是 Rust 链表操作的核心本质是所有权转移——因为节点的 next 字段拥有下一个节点的所有权要重新连接指针就必须先 take() 出来。as_mut().unwrap()获取 Option 内部值的可变引用用于继续遍历和修改。虚拟头节点统一处理交换头两个节点和交换后续节点的逻辑避免单独处理边界条件。掌握 take() 的用法Rust 链表题就成功了一大半。要不要顺带看看递归写法Rust 里递归处理链表和迭代思路差别挺明显的。
返回列表