Skip to content

Commit 1ac89f2

Browse files
committed
dp
1 parent 76b6b4c commit 1ac89f2

File tree

5 files changed

+203
-4
lines changed

5 files changed

+203
-4
lines changed

src/array/no_class.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,50 @@ pub fn solve_sudoku(_board: &mut Vec<Vec<char>>) {
206206
todo!()
207207
}
208208

209+
/// [1793. 好子数组的最大分数](https://leetcode.cn/problems/maximum-score-of-a-good-subarray/?envType=daily-question&envId=2024-03-19)
210+
///
211+
/// 思路:
212+
/// 1. 在不改变最小值的前提下, 延展最多的区间
213+
/// 2. 然后对比这些区间
214+
pub fn maximum_score(nums: Vec<i32>, k: i32) -> i32 {
215+
unimplemented!("暂时不知道怎么解")
216+
}
217+
209218
#[cfg(test)]
210219
mod tests {
211220
use super::*;
212221
use crate::vec2;
213222

223+
#[test]
224+
fn test_maximum_score(){
225+
struct Testcase{
226+
nums: Vec<i32>,
227+
k: i32,
228+
expect: i32,
229+
}
230+
vec![
231+
Testcase{
232+
nums: vec![1, 4, 3, 7, 4, 5],
233+
k: 3,
234+
expect: 15,
235+
},
236+
Testcase{
237+
nums: vec![5, 5, 4, 5, 4, 1, 1, 1],
238+
k: 0,
239+
expect: 20,
240+
},
241+
Testcase{
242+
nums: vec![8182,1273,9847,6230,52,1467,6062,726,4852,4507,2460,2041,500,1025,5524],
243+
k: 8,
244+
expect: 9014
245+
}
246+
].into_iter().enumerate().for_each(|(idx, testcase)|{
247+
let Testcase{nums, k, expect} = testcase;
248+
let actual = maximum_score(nums, k);
249+
assert_eq!(expect, actual, "case {} failed", idx);
250+
});
251+
}
252+
214253
#[test]
215254
#[ignore = "暂时不知道怎么解"]
216255
fn test_solve_sudoku() {

src/array/ser/binary_search.rs

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ where
563563
/// 要求序列满足 `[from, x]` cmp 返回 true, `[x+1, end]` 返回 false
564564
/// 即一开始必须时 true
565565
///
566-
/// 返回的 `I` 不保证 `cmp(I) == true`
566+
/// 返回的 `I` 不保证 `cmp(I) == false`
567567
/// 这个函数保证的是 `(I, end]` cmp不会返回true, `(I, end]` 可能是空
568568
///
569569
/// 做了防溢出, `from`和`end`可以是0, 即传入索引
@@ -623,10 +623,100 @@ pub fn min_capability(nums: Vec<i32>, k: i32) -> i32 {
623623
min
624624
}
625625

626+
627+
/// [2529. 正整数和负整数的最大计数](https://leetcode.cn/problems/maximum-count-of-positive-integer-and-negative-integer)
628+
///
629+
/// 注意: 0 既不是正整数也不是负整数
630+
///
631+
/// 思路: 利用单调性, 找到第一个正整数和最后一个负整数, 然后计算各自的长度
632+
pub fn maximum_count(nums: Vec<i32>) -> i32 {
633+
let first_positive = {
634+
let tmp = first_occur(0, nums.len()-1, |i| nums[i] > 0);
635+
if tmp == 0{
636+
if nums[0] > 0{
637+
0i32
638+
} else {
639+
1i32
640+
}
641+
} else if tmp == nums.len(){
642+
nums.len() as i32
643+
} else {
644+
tmp as i32
645+
}
646+
647+
};
648+
let last_negative = {
649+
let tmp = last_occur(0, nums.len()-1, |i| nums[i] < 0);
650+
if tmp == 0 {
651+
if nums[0] < 0{
652+
1i32
653+
} else {
654+
0i32
655+
}
656+
} else if tmp == nums.len(){
657+
nums.len() as i32
658+
} else {
659+
tmp as i32 + 1
660+
}
661+
};
662+
663+
let pos_len = nums.len() as i32 - first_positive;
664+
let neg_len = last_negative;
665+
666+
pos_len.max(neg_len)
667+
}
668+
626669
#[cfg(test)]
627670
mod tests {
628671
use super::*;
629672

673+
#[test]
674+
fn test_maximum_count(){
675+
struct TestCase{
676+
name: &'static str,
677+
nums: Vec<i32>,
678+
expect: i32,
679+
}
680+
681+
vec![
682+
TestCase{
683+
name: "basic",
684+
nums: vec![-5, -4, -3, -2, -1, 1, 2, 3, 4, 5],
685+
expect: 5,
686+
},
687+
TestCase{
688+
name: "basic 2",
689+
nums: vec![-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
690+
expect: 5,
691+
},
692+
TestCase{
693+
name: "basic 3",
694+
nums: vec![1, 2, 3, 4, 5],
695+
expect: 5,
696+
},
697+
TestCase{
698+
name: "basic 4",
699+
nums: vec![-5, -4, -3, -2, -1],
700+
expect: 5,
701+
},
702+
TestCase{
703+
name: "basic 5",
704+
nums: vec![0, 1, 2, 3, 4, 5],
705+
expect: 5,
706+
},
707+
TestCase{
708+
name: "basic 6",
709+
nums: vec![-5, -4, -3, -2, -1, 0],
710+
expect: 5,
711+
},
712+
]
713+
.iter()
714+
.for_each(|TestCase{name, nums, expect}|{
715+
let actual = maximum_count(nums.to_vec());
716+
assert_eq!(*expect, actual, "{} failed", name);
717+
});
718+
}
719+
630720
#[test]
631721
fn test_min_capability() {
632722
struct TestCase {

src/dp/no_class.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,13 +338,16 @@ pub fn num_factored_binary_trees(mut arr: Vec<i32>) -> i32 {
338338
result as i32
339339
}
340340

341-
342-
343341
#[cfg(test)]
344342
mod test {
345343
use super::*;
346344
use crate::vec2;
347345

346+
#[test]
347+
fn test_combination_sum4(){
348+
349+
}
350+
348351
#[test]
349352
fn test_num_factored_binary_trees() {
350353
struct TestCase {

src/dp/ser.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ pub mod stair;
1010
pub mod stock;
1111
pub mod tree;
1212
pub mod path;
13-
pub mod rob;
13+
pub mod rob;
14+
pub mod combination;

src/dp/ser/combination.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//! 组合问题
2+
3+
/// [377. 组合总和 Ⅳ](https://leetcode.cn/problems/combination-sum-iv)
4+
///
5+
/// 思路:
6+
/// 整体问题可以变成f(n) = f(n-nums[0]) + f(n-nums[1]) + ... + f(n-nums[i])
7+
/// 但是这种朴素的递归操作, 会因为重复计算, 使整体的计算规模扩大
8+
///
9+
/// 可以和 [70. 爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/) 一样, 用dp来解决
10+
///
11+
/// 起点一定是0, 从0开始, 递推到target
12+
pub fn combination_sum4(nums: Vec<i32>, target: i32) -> i32 {
13+
let mut dp = vec![0; target as usize + 1];
14+
dp[0] = 1;
15+
for i in 1..=target {
16+
for &num in nums.iter() {
17+
if i >= num {
18+
dp[i as usize] += dp[(i - num) as usize];
19+
}
20+
}
21+
}
22+
dp[target as usize]
23+
}
24+
25+
#[cfg(test)]
26+
mod test {
27+
use super::*;
28+
use crate::vec2;
29+
30+
#[test]
31+
fn test_combination_sum4() {
32+
struct TestCase {
33+
nums: Vec<i32>,
34+
target: i32,
35+
expected: i32,
36+
}
37+
38+
vec![
39+
TestCase {
40+
nums: vec![1, 2, 3],
41+
target: 4,
42+
expected: 7,
43+
},
44+
TestCase {
45+
nums: vec![9],
46+
target: 3,
47+
expected: 0,
48+
},
49+
]
50+
.into_iter()
51+
.enumerate()
52+
.for_each(
53+
|(
54+
idx,
55+
TestCase {
56+
nums,
57+
target,
58+
expected,
59+
},
60+
)| {
61+
let actual = combination_sum4(nums, target);
62+
assert_eq!(expected, actual, "case {} failed", idx);
63+
},
64+
);
65+
}
66+
}

0 commit comments

Comments
 (0)