Skip to content

Commit 6156fbe

Browse files
committed
LC 287. Find the Duplicate Number (Rust) Revamp
1 parent 1da9ef9 commit 6156fbe

File tree

1 file changed

+55
-7
lines changed

1 file changed

+55
-7
lines changed

leetcode/find-the-duplicate-number.rs

+55-7
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ impl Solution {
1616
/// Time complexity: O(n) - Linear time complexity.
1717
/// Space complexity: O(1) - We use constant extra space.
1818
///
19-
/// Runtime 16 ms Beats 21.90%
20-
/// Memory 4 MB Beats 20.95%
21-
pub fn find_duplicate(nums: Vec<i32>) -> i32 {
19+
/// Runtime 11 ms Beats 59%
20+
/// Memory 4 MB Beats 24%
21+
#[allow(dead_code)]
22+
pub fn find_duplicate_cast(nums: Vec<i32>) -> i32 {
2223
let nums = nums.iter().map(|x| *x as usize).collect::<Vec<usize>>();
2324
let (mut slow, mut fast) = (nums[0], nums[nums[0]]);
2425
while slow != fast {
@@ -33,13 +34,60 @@ impl Solution {
3334
}
3435
slow as i32
3536
}
37+
38+
/// Same logic but do not modify the input vector to cast to usize.
39+
///
40+
/// Time complexity: O(n) - Linear time complexity.
41+
/// Space complexity: O(1) - We use constant extra space.
42+
///
43+
/// Runtime 12 ms Beats 57%
44+
/// Memory 3.10 MB Beats 83%
45+
pub fn find_duplicate(nums: Vec<i32>) -> i32 {
46+
let (mut slow, mut fast) = (nums[0], nums[nums[0] as usize]);
47+
while slow != fast {
48+
slow = nums[slow as usize];
49+
fast = nums[nums[fast as usize] as usize];
50+
}
51+
// Reuse one of the pointers, it can be either.
52+
fast = 0;
53+
while slow != fast {
54+
slow = nums[slow as usize];
55+
fast = nums[fast as usize];
56+
}
57+
fast as i32
58+
}
3659
}
3760

3861
// Tests.
3962
fn main() {
40-
let tests = [(vec![1, 3, 4, 2, 2], 2), (vec![3, 1, 3, 4, 2], 3)];
41-
for t in tests {
42-
assert_eq!(Solution::find_duplicate(t.0), t.1);
63+
let tests = [
64+
(vec![1, 3, 4, 2, 2], 2),
65+
(vec![3, 1, 3, 4, 2], 3),
66+
(vec![3, 3, 3, 3, 3], 3),
67+
];
68+
println!("\n\x1b[92m» Running {} tests...\x1b[0m", tests.len());
69+
let mut success = 0;
70+
for (i, t) in tests.iter().enumerate() {
71+
let res = Solution::find_duplicate(t.0.clone());
72+
if res == t.1 {
73+
success += 1;
74+
println!("\x1b[92m✔\x1b[95m Test {} passed!\x1b[0m", i);
75+
} else {
76+
println!(
77+
"\x1b[31mx\x1b[95m Test {} failed expected: {:?} but got {}!!\x1b[0m",
78+
i, t.1, res
79+
);
80+
}
81+
}
82+
println!();
83+
if success == tests.len() {
84+
println!("\x1b[30;42m✔ All tests passed!\x1b[0m")
85+
} else if success == 0 {
86+
println!("\x1b[31mx \x1b[41;37mAll tests failed!\x1b[0m")
87+
} else {
88+
println!(
89+
"\x1b[31mx\x1b[95m {} tests failed!\x1b[0m",
90+
tests.len() - success
91+
)
4392
}
44-
println!("\x1b[92m» All tests passed!\x1b[0m")
4593
}

0 commit comments

Comments
 (0)