ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

元宝 LeetCode 61. 旋转链表 Rust实现

元宝    LeetCode 61. 旋转链表 Rust实现 下面是 LeetCode 61 “旋转链表” 的 Rust 实现。代码包含了详细注释以解释思路。解题思路边界处理如果链表为空或“k 0”直接返回。计算长度遍历链表得到长度“len”同时将“k” 对“len” 取模因为移动“len” 次等于回到原样。找到断点使用哑节点dummy node和可变引用遍历到新尾节点即倒数第“k1” 个节点。重新连接将新尾节点后面的部分后“k” 个节点作为新的头节点。遍历新链表找到末尾将其“next” 指向原来的头节点即哑节点的“next”。断开新尾节点与原头节点的连接。Rust 代码实现// Definition for singly-linked list.// LeetCode 环境中已提供这里列出以便本地测试#[derive(PartialEq, Eq, Clone, Debug)]pub struct ListNode {pub val: i32,pub next: OptionBox,}impl ListNode {#[inline]fn new(val: i32) - Self {ListNode { next: None, val }}}pub struct Solution;impl Solution {pub fn rotate_right(head: OptionBox, k: i32) - OptionBox {// 1. 处理空链表或不需要旋转的情况if head.is_none() || k 0 {return head;}// 2. 计算链表长度 let mut len 0; let mut cur head; while let Some(node) cur { len 1; cur node.next; } // 对长度取模如果刚好是长度的整数倍则无需操作 let k (k as usize) % len; if k 0 { return head; } // 3. 使用哑节点方便处理头节点移动 let mut dummy Box::new(ListNode { val: 0, next: head }); // prev 用于找到新的尾节点移动 len - k 步 let mut prev mut dummy; for _ in 0..(len - k) { prev prev.next.as_mut().unwrap(); } // 4. 拿走后 k 个节点作为新头并断开连接 let mut new_head prev.next.take(); // 5. 找到新头的末尾连接原来的头 let mut tail mut new_head; while let Some(node) tail { if node.next.is_none() { // 将原链表的前半部分接到新头末尾 node.next dummy.next; break; } tail mut node.next; } // 6. 返回新头节点 new_head }}// 测试用例#[cfg(test)]mod tests {use super:;fn vec_to_list(nums: Veci32) - OptionBoxListNode { let mut head None; let mut tail mut head; for n in nums { let node Box::new(ListNode::new(n)); *tail Some(node); tail mut tail.as_mut().unwrap().next; } head } #[test] fn test_rotate() { let head vec_to_list(vec![1, 2, 3, 4, 5]); let result Solution::rotate_right(head, 2); // 验证结果... println!({:?}, result); }}关键点说明Rust 特性所有权与借用通过“as_mut().unwrap()” 获取节点的可变引用安全地遍历和修改链表。“Option::take”“prev.next.take()” 会将“prev.next” 设置为“None” 并返回其拥有的值这让我们能干净地切断链表而不触发借用检查错误。时间复杂度O(n)其中 n 是链表长度两次遍历可合并为一次闭链后直接找点但两次更清晰。空间复杂度O(1)只使用了常数级别的额外指针。
返回列表