You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Rust中反转部分链表?LeetCode问题代码修复求助

修复LeetCode「反转链表II」的Rust实现错误

错误原因分析

  1. 借用规则冲突:代码中先通过fake_head.as_mut()创建了可变引用curr,随后又对fake_head执行clone()(不可变借用),Rust不允许同一对象同时存在可变和不可变引用,导致编译错误。
  2. 所有权移动错误:curr.next是可变引用背后的Option<Box<ListNode>>,直接将其传递给reverse_list会尝试移动所有权,但Rust不允许从可变引用背后直接移动值。
  3. 无效的所有权消耗:后续遍历reversed时多次调用unwrap(),每次调用都会消耗Option的所有权,导致后续无法再访问该值。

修复后的完整代码

// 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 {
    // 反转前n个节点,返回(反转后的头, 剩余未反转的链表)
    fn reverse_n(mut head: Option<Box<ListNode>>, n: usize) -> (Option<Box<ListNode>>, Option<Box<ListNode>>) {
        let mut prev = None;
        let mut curr = head;
        for _ in 0..n {
            if let Some(mut node) = curr {
                let next = node.next;
                node.next = prev;
                prev = Some(node);
                curr = next;
            }
        }
        (prev, curr)
    }

    pub fn reverse_between(head: Option<Box<ListNode>>, left: i32, right: i32) -> Option<Box<ListNode>> {
        let mut fake_head = Box::new(ListNode::new(-1));
        fake_head.next = head;
        let mut prev_node = &mut fake_head;

        // 移动到反转区间的前一个节点
        for _ in 0..(left - 1) {
            prev_node = prev_node.next.as_mut().unwrap();
        }

        // 取出要反转的区间的头节点
        let reverse_start = prev_node.next.take();
        let n = (right - left + 1) as usize;
        
        // 反转前n个节点,得到反转后的头和剩余链表
        let (reversed_head, remaining) = Self::reverse_n(reverse_start, n);
        
        // 拼接反转后的头到前驱节点后
        prev_node.next = reversed_head;

        // 找到反转后的尾节点,拼接剩余链表
        let mut reversed_tail = &mut prev_node.next;
        for _ in 0..(n - 1) {
            reversed_tail = &mut reversed_tail.as_mut().unwrap().next;
        }
        reversed_tail.as_mut().unwrap().next = remaining;

        fake_head.next
    }
}

关键修改说明

  1. 新增reverse_n函数:专门反转链表的前n个节点,同时返回反转后的头节点和剩余未反转的链表,避免了原代码中反转整个链表的低效问题,也方便后续拼接。
  2. 调整节点定位逻辑:先单独找到反转区间的前驱节点prev_node,避免同时持有多个冲突的引用。
  3. 使用take()安全转移所有权:通过prev_node.next.take()取出要反转的区间头节点,同时将原位置设为None,解决了所有权移动的问题。
  4. 安全遍历反转后的链表:通过可变引用遍历找到反转后的尾节点,避免了unwrap()消耗所有权的问题。

内容的提问来源于stack exchange,提问作者mascai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 23:03:10