From 7487430bc34bc2fb9bc189dda0e0e73bb23f0dbb Mon Sep 17 00:00:00 2001 From: Xu Shaohua Date: Fri, 24 May 2024 11:21:56 +0800 Subject: [PATCH] leetcode: Add 0784 --- .../0377.combination-sum-iv/Cargo.toml | 7 + src/leetcode/0377.combination-sum-iv/index.md | 4 + .../0377.combination-sum-iv/src/main.rs | 128 ++++++++++++++++++ .../0784.letter-case-permutation/Cargo.toml | 7 + .../0784.letter-case-permutation/index.md | 4 + .../0784.letter-case-permutation/src/main.rs | 68 ++++++++++ 6 files changed, 218 insertions(+) create mode 100644 src/leetcode/0377.combination-sum-iv/Cargo.toml create mode 100644 src/leetcode/0377.combination-sum-iv/index.md create mode 100644 src/leetcode/0377.combination-sum-iv/src/main.rs create mode 100644 src/leetcode/0784.letter-case-permutation/Cargo.toml create mode 100644 src/leetcode/0784.letter-case-permutation/index.md create mode 100644 src/leetcode/0784.letter-case-permutation/src/main.rs diff --git a/src/leetcode/0377.combination-sum-iv/Cargo.toml b/src/leetcode/0377.combination-sum-iv/Cargo.toml new file mode 100644 index 000000000..bd892f02b --- /dev/null +++ b/src/leetcode/0377.combination-sum-iv/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "lc-0377-combination-sum-iv" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] diff --git a/src/leetcode/0377.combination-sum-iv/index.md b/src/leetcode/0377.combination-sum-iv/index.md new file mode 100644 index 000000000..77a618ba8 --- /dev/null +++ b/src/leetcode/0377.combination-sum-iv/index.md @@ -0,0 +1,4 @@ + +# + +[问题描述](../problems/) diff --git a/src/leetcode/0377.combination-sum-iv/src/main.rs b/src/leetcode/0377.combination-sum-iv/src/main.rs new file mode 100644 index 000000000..ca9a01b73 --- /dev/null +++ b/src/leetcode/0377.combination-sum-iv/src/main.rs @@ -0,0 +1,128 @@ +// Copyright (c) 2024 Xu Shaohua . All rights reserved. +// Use of this source is governed by General Public License that can be found +// in the LICENSE file. + +// Backtracking +pub fn combination_sum1(nums: Vec, target: i32) -> i32 { + fn backtracking( + nums: &[i32], + target: i32, + max_level: usize, + path: &mut Vec, + res: &mut Vec>, + ) { + println!("target: {target}, res count: {}", res.len()); + // 终止条件就是 target 不大于 0. + if target == 0 { + res.push(path.clone()); + } + if target <= 0 || path.len() >= max_level { + return; + } + + // 遍历所有元素. + for &num in nums.iter() { + if num <= target && path.len() < max_level { + // 访问元素 + path.push(num); + + // 递归搜索 + backtracking(nums, target - num, max_level, path, res); + + // 撤销访问 + path.pop(); + } + } + } + + debug_assert!((1..=200).contains(&nums.len())); + debug_assert!((1..=1000).contains(&target)); + + let mut nums = nums; + nums.sort_unstable(); + + let max_level: usize = (target / nums[0] + 1) as usize; + + // 保存所有结果. + let mut res: Vec> = Vec::new(); + // 保存当前路径. + let mut path: Vec = Vec::new(); + + backtracking(&nums, target, max_level, &mut path, &mut res); + //println!("res: {res:?}"); + res.len() as i32 +} + +pub fn combination_sum2(nums: Vec, target: i32) -> i32 { + fn backtracking(nums: &[i32], target: i32, path: &mut Vec, count: &mut i32) { + println!("target: {target}, res count: {count}"); + // 终止条件就是 target 不大于 0. + if target == 0 { + *count += 1; + } + if target <= 0 { + return; + } + + // 遍历所有元素. + for &num in nums.iter() { + if num <= target { + // 访问元素 + path.push(num); + + // 递归搜索 + backtracking(nums, target - num, path, count); + + // 撤销访问 + path.pop(); + } + } + } + + debug_assert!((1..=200).contains(&nums.len())); + debug_assert!((1..=1000).contains(&target)); + + // 保存所有结果. + let mut count: i32 = 0; + // 保存当前路径. + let mut path: Vec = Vec::new(); + + backtracking(&nums, target, &mut path, &mut count); + count +} + +pub type SolutionFn = fn(Vec, i32) -> i32; + +fn check_solution(func: SolutionFn) { + let nums = vec![1, 2, 3]; + let target = 4; + assert_eq!(func(nums, target), 7); + + let nums = vec![9]; + let target = 3; + assert_eq!(func(nums, target), 0); + + // FIXME(Shaohua): Timeout + //let nums = vec![1, 2, 3]; + //let target = 32; + //assert_eq!(func(nums, target), 0); + + //let nums = vec![4, 2, 1]; + //let target = 32; + //assert_eq!(func(nums, target), 0); +} + +fn main() { + check_solution(combination_sum1); + check_solution(combination_sum2); +} + +#[cfg(test)] +mod tests { + use super::{check_solution, combination_sum1}; + + #[test] + fn test_combination_sum1() { + check_solution(combination_sum1); + } +} diff --git a/src/leetcode/0784.letter-case-permutation/Cargo.toml b/src/leetcode/0784.letter-case-permutation/Cargo.toml new file mode 100644 index 000000000..d12e856df --- /dev/null +++ b/src/leetcode/0784.letter-case-permutation/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "lc-0784-letter-case-permutation" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] diff --git a/src/leetcode/0784.letter-case-permutation/index.md b/src/leetcode/0784.letter-case-permutation/index.md new file mode 100644 index 000000000..77a618ba8 --- /dev/null +++ b/src/leetcode/0784.letter-case-permutation/index.md @@ -0,0 +1,4 @@ + +# + +[问题描述](../problems/) diff --git a/src/leetcode/0784.letter-case-permutation/src/main.rs b/src/leetcode/0784.letter-case-permutation/src/main.rs new file mode 100644 index 000000000..4bd47abe6 --- /dev/null +++ b/src/leetcode/0784.letter-case-permutation/src/main.rs @@ -0,0 +1,68 @@ +// Copyright (c) 2024 Xu Shaohua . All rights reserved. +// Use of this source is governed by General Public License that can be found +// in the LICENSE file. + +// Backtracking +pub fn letter_case_permutation1(s: String) -> Vec { + fn backtracking(chars: &[char], index: usize, path: &mut Vec, res: &mut Vec) { + // 终止条件就是所有字符都已经访问过. + if index == chars.len() { + res.push(String::from_iter(path.iter())); + return; + } + + // 访问当前元素. + let chr: char = chars[index]; + // 如果当前字符是数字, 就直接访问下个元素. + path.push(chr); + backtracking(chars, index + 1, path, res); + path.pop(); + + // 如果当前字符是字母, 就要处理大写和小写. + if chr.is_ascii_alphabetic() { + path.push(chr.to_ascii_uppercase()); + backtracking(chars, index + 1, path, res); + path.pop(); + } + } + + let chars: Vec = s.to_ascii_lowercase().chars().collect(); + + // 存储所有结果. + let mut res: Vec = Vec::new(); + // 存储当前的路径. + let mut path: Vec = Vec::new(); + backtracking(&chars, 0, &mut path, &mut res); + res +} + +pub type SolutionFn = fn(String) -> Vec; + +fn check_solution(func: SolutionFn) { + let s = "a1b2".to_owned(); + let expected = vec![ + "a1b2".to_owned(), + "a1B2".to_owned(), + "A1b2".to_owned(), + "A1B2".to_owned(), + ]; + assert_eq!(func(s), expected); + + let s = "3z4".to_owned(); + let expected = vec!["3z4".to_owned(), "3Z4".to_owned()]; + assert_eq!(func(s), expected); +} + +fn main() { + check_solution(letter_case_permutation1); +} + +#[cfg(test)] +mod tests { + use super::{check_solution, letter_case_permutation1}; + + #[test] + fn test_letter_case_permutation1() { + check_solution(letter_case_permutation1); + } +}