Skip to content

Commit

Permalink
leetcode: Add 0784
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed May 24, 2024
1 parent 8d62562 commit 7487430
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/leetcode/0377.combination-sum-iv/Cargo.toml
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]
4 changes: 4 additions & 0 deletions src/leetcode/0377.combination-sum-iv/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

#

[问题描述](../problems/)
128 changes: 128 additions & 0 deletions src/leetcode/0377.combination-sum-iv/src/main.rs
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);
}
}
7 changes: 7 additions & 0 deletions src/leetcode/0784.letter-case-permutation/Cargo.toml
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]
4 changes: 4 additions & 0 deletions src/leetcode/0784.letter-case-permutation/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

#

[问题描述](../problems/)
68 changes: 68 additions & 0 deletions src/leetcode/0784.letter-case-permutation/src/main.rs
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);
}
}

0 comments on commit 7487430

Please sign in to comment.