-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
218 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "lc-0377-combination-sum-iv" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
# | ||
|
||
[问题描述](../problems/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// Copyright (c) 2024 Xu Shaohua <[email protected]>. 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<i32>, target: i32) -> i32 { | ||
fn backtracking( | ||
nums: &[i32], | ||
target: i32, | ||
max_level: usize, | ||
path: &mut Vec<i32>, | ||
res: &mut Vec<Vec<i32>>, | ||
) { | ||
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<i32>> = Vec::new(); | ||
// 保存当前路径. | ||
let mut path: Vec<i32> = Vec::new(); | ||
|
||
backtracking(&nums, target, max_level, &mut path, &mut res); | ||
//println!("res: {res:?}"); | ||
res.len() as i32 | ||
} | ||
|
||
pub fn combination_sum2(nums: Vec<i32>, target: i32) -> i32 { | ||
fn backtracking(nums: &[i32], target: i32, path: &mut Vec<i32>, 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<i32> = Vec::new(); | ||
|
||
backtracking(&nums, target, &mut path, &mut count); | ||
count | ||
} | ||
|
||
pub type SolutionFn = fn(Vec<i32>, 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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[package] | ||
name = "lc-0784-letter-case-permutation" | ||
version = "0.1.0" | ||
edition = "2021" | ||
publish = false | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
|
||
# | ||
|
||
[问题描述](../problems/) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (c) 2024 Xu Shaohua <[email protected]>. 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<String> { | ||
fn backtracking(chars: &[char], index: usize, path: &mut Vec<char>, res: &mut Vec<String>) { | ||
// 终止条件就是所有字符都已经访问过. | ||
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<char> = s.to_ascii_lowercase().chars().collect(); | ||
|
||
// 存储所有结果. | ||
let mut res: Vec<String> = Vec::new(); | ||
// 存储当前的路径. | ||
let mut path: Vec<char> = Vec::new(); | ||
backtracking(&chars, 0, &mut path, &mut res); | ||
res | ||
} | ||
|
||
pub type SolutionFn = fn(String) -> Vec<String>; | ||
|
||
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); | ||
} | ||
} |