diff --git a/src/dynamic_programming/burst_balloons.rs b/src/dynamic_programming/burst_balloons.rs new file mode 100644 index 00000000000..cc2d67527d2 --- /dev/null +++ b/src/dynamic_programming/burst_balloons.rs @@ -0,0 +1,101 @@ +/* +Inspired by Leetcode 312 : https://leetcode.com/problems/burst-balloons/ + +You are given n balloons, indexed from 0 to n - 1. Each balloon is painted with a number on it represented by an array nums. You are asked to burst all the balloons. + +If you burst the ith balloon, you will get nums[i - 1] * nums[i] * nums[i + 1] coins. If i - 1 or i + 1 goes out of bounds of the array, then treat it as if there is a balloon with a 1 painted on it. + +Return the maximum coins you can collect by bursting the balloons wisely. + +Example 1: + +Input: nums = [3,1,5,8] +Output: 167 +Explanation: +nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> [] +coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167 +Example 2: + +Input: nums = [1,5] +Output: 10 + + +Constraints: + +n == nums.length +1 <= n <= 300 +0 <= nums[i] <= 100 + + */ + + use std::cmp::max; + +struct Solution; + +impl Solution { + pub fn max_coins(nums: Vec) -> i32 { + let n = nums.len(); + let mut f = vec![vec![0; n]; n]; + + // f(i,j) = if we only play in the range [i,j], what is the maximum score? + for len in 0..n { + for i in 0..n - len { + let j = i + len; + for x in i..=j { + // In the range [i,j], if we burst balloon x last, what is the maximum score? + let mut score = nums[x]; + if i > 0 { + score *= nums[i - 1]; + } + if j < n - 1 { + score *= nums[j + 1]; + } + if x > i { + score += f[i][x - 1]; + } + if x < j { + score += f[x + 1][j]; + } + f[i][j] = max(f[i][j], score); + } + } + } + f[0][n - 1] + } +} + +fn main() { + let test_cases = vec![ + vec![3, 1, 5, 8], // Example from the problem + vec![1, 5], // Small case + vec![1, 2, 3], // Incremental values + vec![3, 1, 5], // Another small case + vec![7, 9, 8, 0, 7], // Mixed values + vec![9, 76, 64, 21], // Larger values + ]; + + for (i, nums) in test_cases.iter().enumerate() { + println!("Test case {}: nums = {:?}, max coins = {}", i + 1, nums, Solution::max_coins(nums.clone())); + } +} + +#[cfg(test)] +mod tests { + use super::Solution; + + #[test] + fn test_max_coins() { + let test_cases = vec![ + (vec![3, 1, 5, 8], 167), + (vec![1, 5], 10), + (vec![1, 2, 3], 12), + (vec![3, 1, 5], 35), + (vec![7, 9, 8, 0, 7], 665), + (vec![9, 76, 64, 21], 123408), + ]; + + for (nums, expected) in test_cases { + assert_eq!(Solution::max_coins(nums), expected); + } + } +} diff --git a/src/searching/floyd_cycle_detection.rs b/src/searching/floyd_cycle_detection.rs new file mode 100644 index 00000000000..491dda8af77 --- /dev/null +++ b/src/searching/floyd_cycle_detection.rs @@ -0,0 +1,49 @@ +/// Implementation of Floyd's Cycle Detection algorithm -> Hare and Tortoise algorithm +/// Given an array of integers containing 'n + 1' integers, where each +/// integer is in the range [1, n] inclusive. If there is only one duplicate +/// number in the input array, this algorithm returns the duplicate number in +/// O(1) space and the time complexity is less than O(n^2) without modifying the +/// original array, otherwise, it returns -1. +/// +/// Author: Tashvik (https://github.com/tashviks) + +/// Function to find the duplicate number using Floyd's Cycle Detection algorithm +fn find_duplicate_number(nums: &[u32]) -> Option { + if nums.is_empty() { + return None; // No duplicates if array is empty + } + + let mut tortoise = nums[0]; + let mut hare = nums[0]; + + // Phase 1: Finding the intersection point + loop { + tortoise = nums[tortoise as usize]; + hare = nums[nums[hare as usize] as usize]; + + if tortoise == hare { + break; + } + } + + // Phase 2: Finding the duplicate number + tortoise = nums[0]; + while tortoise != hare { + tortoise = nums[tortoise as usize]; + hare = nums[hare as usize]; + } + + Some(tortoise) +} + +fn main() { + // Test cases + let array1 = vec![3, 4, 8, 5, 9, 1, 2, 6, 7, 4]; + println!("Array 1: {:?}", find_duplicate_number(&array1)); // Outputs: Some(4) + + let array2 = vec![1, 2, 3, 4, 2]; + println!("Array 2: {:?}", find_duplicate_number(&array2)); // Outputs: Some(2) + + let array3: Vec = vec![]; + println!("Array 3: {:?}", find_duplicate_number(&array3)); // Outputs: None +}