use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { val: i32, next: Option<Rc<RefCell<Node>>>, } fn has_cycle(head: Option<Rc<RefCell<Node>>>) -> bool { let mut slow = head.clone(); let mut fast = head.clone(); while fast.is_some() && fast.as_ref().unwrap().borrow().next.is_some() { slow = slow.unwrap().borrow().next.clone(); fast = fast.unwrap().borrow().next.clone().unwrap().borrow().next.clone(); if slow.is_some() && slow == fast { return true; } } false } fn main() { let node1 = Rc::new(RefCell::new(Node { val: 1, next: None })); let node2 = Rc::new(RefCell::new(Node { val: 2, next: None })); let node3 = Rc::new(RefCell::new(Node { val: 3, next: None })); node1.borrow_mut().next = Some(node2.clone()); node2.borrow_mut().next = Some(node3.clone()); node3.borrow_mut().next = Some(node1.clone()); // creates cycle println!("{}", has_cycle(Some(node1))); }
The code creates a linked list with a cycle by linking the last node back to the first node. Floyd's algorithm uses two pointers moving at different speeds. When there is a cycle, the fast pointer will eventually meet the slow pointer, so the function returns true.
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { val: i32, next: Option<Rc<RefCell<Node>>>, } fn has_cycle(head: Option<Rc<RefCell<Node>>>) -> bool { let mut slow = head.clone(); let mut fast = head.clone(); while fast.is_some() && fast.as_ref().unwrap().borrow().next.is_some() { slow = slow.unwrap().borrow().next.clone(); fast = fast.unwrap().borrow().next.clone().unwrap().borrow().next.clone(); if slow.is_some() && slow == fast { return true; } } false } fn main() { let node1 = Rc::new(RefCell::new(Node { val: 1, next: None })); let node2 = Rc::new(RefCell::new(Node { val: 2, next: None })); let node3 = Rc::new(RefCell::new(Node { val: 3, next: None })); node1.borrow_mut().next = Some(node2.clone()); node2.borrow_mut().next = Some(node3.clone()); // no cycle created println!("{}", has_cycle(Some(node1))); }
The linked list has no cycle because the last node's next is None. The fast pointer reaches the end without meeting the slow pointer, so the function returns false.
fn has_cycle(head: Option<Box<Node>>) -> bool { let mut slow = head.clone(); let mut fast = head.clone(); while fast.is_some() && fast.as_ref().unwrap().next.is_some() { slow = slow.unwrap().next; fast = fast.unwrap().next.unwrap().next; if slow == fast { return true; } } false } struct Node { val: i32, next: Option<Box<Node>>, }
The code tries to assign 'head' to both 'slow' and 'fast', but 'head' is moved into 'slow' on the first assignment, so the second assignment to 'fast' causes a compilation error because 'head' is no longer available.
Floyd's algorithm uses two pointers moving at different speeds (slow and fast). If there is a cycle, the fast pointer will eventually catch up to the slow pointer inside the cycle, confirming its presence without extra memory.
use std::rc::Rc; use std::cell::RefCell; #[derive(Debug)] struct Node { val: i32, next: Option<Rc<RefCell<Node>>>, } fn has_cycle(head: Option<Rc<RefCell<Node>>>) -> bool { let mut slow = head.clone(); let mut fast = head.clone(); while fast.is_some() && fast.as_ref().unwrap().borrow().next.is_some() { slow = slow.unwrap().borrow().next.clone(); fast = fast.unwrap().borrow().next.clone().unwrap().borrow().next.clone(); if slow.is_some() && slow == fast { return true; } } false } fn main() { let node1 = Rc::new(RefCell::new(Node { val: 1, next: None })); let node2 = Rc::new(RefCell::new(Node { val: 2, next: None })); let node3 = Rc::new(RefCell::new(Node { val: 3, next: None })); let node4 = Rc::new(RefCell::new(Node { val: 4, next: None })); let node5 = Rc::new(RefCell::new(Node { val: 5, next: None })); node1.borrow_mut().next = Some(node2.clone()); node2.borrow_mut().next = Some(node3.clone()); node3.borrow_mut().next = Some(node4.clone()); node4.borrow_mut().next = Some(node5.clone()); node5.borrow_mut().next = Some(node3.clone()); // cycle starts at node3 println!("{}", has_cycle(Some(node1))); }
The linked list has a cycle starting at node 3. Floyd's algorithm detects this by the fast pointer eventually catching the slow pointer inside the cycle, so the function returns true.
