diff --git a/src/lib.rs b/src/lib.rs index 4a2f141..9f8a9ce 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,3 +14,5 @@ pub mod p13_roman_to_integer; pub mod p14_longest_common_prefix; pub mod p15_3sum; pub mod p16_3sum_closest; +pub mod p17_letter_combinations_of_a_phone_number; +pub mod p18_4sum; diff --git a/src/p17_letter_combinations_of_a_phone_number.rs b/src/p17_letter_combinations_of_a_phone_number.rs new file mode 100644 index 0000000..0caf26b --- /dev/null +++ b/src/p17_letter_combinations_of_a_phone_number.rs @@ -0,0 +1,46 @@ +pub struct Solution; +impl Solution { + const LETTER_GROUPS: [&'static[char]; 8] = [ + &['a','b','c'], &['d','e','f'], &['g','h','i'], + &['j','k','l'], &['m','n','o'], &['p','q','r','s'], + &['t','u','v'], &['w','x','y','z'] + ]; + + pub fn letter_combinations(digits: String) -> Vec { + if digits.is_empty() { return vec![]; } + let mut result = vec!["".to_string()]; + for b in digits.bytes() { + let group_index = b - b'0' - 2; + let group = Self::LETTER_GROUPS[group_index as usize]; + let extend_size = result.len(); + for _ in 0..group.len()-1 { result.extend_from_within(..extend_size); } + for (i, s) in result.iter_mut().enumerate() { + let index = i / extend_size; + s.push(group[index]); + } + } + return result; + } +} + +#[test] +fn test1() { + let mut actual = Solution::letter_combinations("23".to_string()); + actual.sort(); + assert_eq!(actual, vec![ + "ad".to_string(), "ae".to_string(), "af".to_string(), + "bd".to_string(), "be".to_string(), "bf".to_string(), + "cd".to_string(), "ce".to_string(), "cf".to_string() + ]); +} + +#[test] +fn test2() { + assert_eq!(Solution::letter_combinations(String::new()), Vec::::new()); +} + +#[test] +fn test3() { + assert_eq!(Solution::letter_combinations("2".to_string()), + vec!["a".to_string(), "b".to_string(), "c".to_string()]); +} diff --git a/src/p18_4sum.rs b/src/p18_4sum.rs new file mode 100644 index 0000000..67fe639 --- /dev/null +++ b/src/p18_4sum.rs @@ -0,0 +1,55 @@ +pub struct Solution; +impl Solution { + pub fn four_sum(mut nums: Vec, target: i32) -> Vec> { + let mut result = vec![]; + if nums.len() < 4 { return result; } + nums.sort(); + for i in 0..nums.len()-3 { + if i > 0 && nums[i - 1] == nums[i] { continue; } + for j in i+1..nums.len()-2 { + if j > i + 1 && nums[j - 1] == nums[j] { continue; } + let (mut k, mut l) = (j + 1, nums.len() - 1); + while k < l { + if k > j + 1 && nums[k - 1] == nums[k] { + k += 1; continue; + } + if l < nums.len() - 1 && nums[l + 1] == nums[l] { + l -= 1; continue; + } + // num is in range [-10^9; 10^9], possibility of overflow + let Some(sum) = (nums[i] + nums[j]).checked_add(nums[k] + nums[l]) + else { k += 1; continue; }; + match (sum - target).signum() { + -1 => { k += 1; }, + 1 => { l -= 1; }, + 0 => { + result.push(vec![nums[i], nums[j], nums[k], nums[l]]); + k += 1; l -= 1; + }, + _ => () + } + } + } + } + return result; + } +} + +#[test] +fn test1() { + let mut actual = Solution::four_sum(vec![1,0,-1,0,-2,2], 0); + actual.iter_mut().for_each(|v| v.sort()); + assert_eq!(actual, vec![ + vec![-2,-1,1,2], vec![-2,0,0,2], vec![-1,0,0,1] + ]); +} + +#[test] +fn test2() { + assert_eq!(Solution::four_sum(vec![2,2,2,2,2], 8), vec![vec![2,2,2,2]]); +} + +#[test] +fn test3() { + assert_eq!(Solution::four_sum(vec![1000000000,1000000000,1000000000,1000000000], -294967296), Vec::>::new()); +}