Skip to content

Commit 690ed30

Browse files
committed
do hard
1 parent 04f94a7 commit 690ed30

9 files changed

+716
-30
lines changed

Basic.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ with_stock_balances[i][k] = max(with_stock_balances[i-1][k], no_stock_balances[i
269269
* Similar to [84. Largest Rectangle in Histogram](src/problem/p0084_largest_rectangle_in_histogram.rs), solved with monotonic stack.
270270
* [87. Scramble String](src/problem/p0087_scramble_string.rs)
271271
* Bottom-up approach with the increment on the substring length
272-
* To redo and review with top-down approach with memoization.
272+
* TODO: review with top-down approach with memoization.
273273
* [135. Candy](src/problem/p0135_candy.rs)
274274
* Smart tricks
275275
* [149. Max Points on a Line](src/problem/p0149_max_points_on_a_line.rs)
@@ -309,6 +309,23 @@ with_stock_balances[i][k] = max(with_stock_balances[i-1][k], no_stock_balances[i
309309
* Prepare a vector of prefix sum S
310310
* For each i, count j > i s.t S\[j\]-S\[i\] within the range
311311
* Leverage the MergeSort, similar to [315. Count of Smaller Numbers After Self](src/problem/p0315_count_of_smaller_numbers_after_self.rs).
312+
* [330. Patching Array](src/problem/p0330_patching_array.rs)
313+
* Smart Tricks by Recursion: Assume the previous i number can attain \[0,next_miss]),
314+
* If num[i] <= next_miss:the range can be augment to [0, next_miss+num[i]) by considering num[i].
315+
* Else:pad the array with next_muss to augment into [0, next_miss*2)
316+
* [335. Self Crossing](src/problem/p0335_self_crossing.rs)
317+
* Assume edge i to be first crossed, enumerate three canonical scenarios, in which the edge is crossed by i+4,i+5,and i+6.
318+
* Relate the scenario with the edge length conditions.
319+
* [336. Palindrome Pairs](src/problem/p0336_palindrome_pairs.rs)
320+
* Build a trie for the reversed strings
321+
* [352. Data Stream as Disjoint Intervals](src/problem/p0352_data_stream_as_disjoint_intervals.rs)
322+
* Ordered BTree Map
323+
* [354. Russian Doll Envelopes](src/problem/p0354_russian_doll_envelopes.rs)
324+
* Longest Increasing Subsequence
325+
* [363. Max Sum of Rectangle No Larger Than K](src/problem/p0363_max_sum_of_rectangle_no_larger_than_k.rs)
326+
* Two related subproblems:
327+
* Max Sum Submatrix (KaDane's Algorithm)
328+
* Subarray with the sum no larger than k (Compute during the Merge Sort, similar to [327. Count of Range Sum](src/problem/p0327_count_of_range_sum.rs))
312329

313330
# [Collected Template](src/problem/p0000_template.rs)
314331
* Data structure:

src/problem/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,9 @@ mod p0315_count_of_smaller_numbers_after_self;
211211
mod p0321_create_maximum_number;
212212
mod p0327_count_of_range_sum;
213213
mod p0329_longest_increasing_path_in_a_matrix;
214+
mod p0330_patching_array;
215+
mod p0335_self_crossing;
216+
mod p0336_palindrome_pairs;
217+
mod p0352_data_stream_as_disjoint_intervals;
218+
mod p0354_russian_doll_envelopes;
219+
mod p0363_max_sum_of_rectangle_no_larger_than_k;

src/problem/p0000_template.rs

Lines changed: 50 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -966,44 +966,36 @@ impl MapUtil {
966966
map.insert(3, "a".to_owned());
967967
map.insert(5, "b".to_owned());
968968
map.insert(8, "c".to_owned());
969+
970+
use std::ops::Range; // [start, end)
971+
use std::ops::RangeInclusive; // [start, end]
972+
973+
use std::ops::RangeTo; // (-inf, end)
974+
use std::ops::RangeToInclusive; // (-inf, end]
975+
use std::ops::RangeFrom; // [start, +inf)
976+
use std::ops::RangeFull; // [-inf, +inf]
969977
// key, value typed with &
970-
for (key, value) in map.range((Included(&4), Included(&8))) {
971-
// println!("{}: {}", key, value);
978+
// for (key, value) in map.range(Range{start:3, end:7}) {
979+
for (key, value) in map.range(RangeInclusive::new(3, 5)) {
980+
println!("{}: {}", key, value);
972981
}
973982

974-
for (key, value) in map.range_mut((Included(&4), Included(&8))) {
983+
for (key, value) in map.range_mut(RangeFull) {
975984
// *key = 1; key is always immutable.
976-
*value = "asdf".to_owned();
985+
*value = "d".to_owned();
977986
// println!("{}: {}", key, value);
978987
}
979988

980-
// Fast Init
981-
let a: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
982-
let b: HashSet<i32> = [4, 2, 3, 4].iter().cloned().collect();
989+
// last key less
990+
assert_eq!(map.range(RangeTo{end : 5}).next_back(), Some((&3, &"d".to_owned())));
983991

984-
// Can be seen as `a - b`.
985-
// x typed as &
986-
for x in a.difference(&b) {
987-
// println!("{}", x); // Print 1
988-
}
989-
990-
let diff: HashSet<i32> = a.difference(&b).cloned().collect();
991-
assert_eq!(diff, [1].iter().cloned().collect());
992-
993-
// Note that difference is not symmetric,
994-
// and `b - a` means something else:
995-
// no cloned to get a set of reference.
996-
let diff: HashSet<&i32> = b.difference(&a).collect();
997-
assert_eq!(diff, [4].iter().collect());
998-
999-
let intersection: HashSet<i32> = a.intersection(&b).cloned().collect();
1000-
assert_eq!(intersection, [2,3].iter().cloned().collect());
1001-
1002-
let union: HashSet<i32> = a.union(&b).cloned().collect();
1003-
assert_eq!(union, [1,2,3,4].iter().cloned().collect());
1004-
assert!(!a.is_subset(&b));
1005-
assert!(!a.is_superset(&b));
992+
// last key less or equal to
993+
assert_eq!(map.range(RangeToInclusive{end : 5}).next_back(), Some((&5, &"d".to_owned())));
1006994

995+
// first key greater or equal to
996+
assert_eq!(map.range(RangeFrom{start : 7}).next(), Some((&8, &"d".to_owned())));
997+
assert_eq!(map.range(RangeFrom{start : 8}).next(), Some((&8, &"d".to_owned())));
998+
assert_eq!(map.range(RangeFrom{start : 9}).next(), None);
1007999
}
10081000

10091001
pub fn hashset_misc() {
@@ -1047,6 +1039,35 @@ impl MapUtil {
10471039
// first and last
10481040
assert_eq!(set.iter().next(), Some(&3));
10491041
assert_eq!(set.iter().next_back(), Some(&8));
1042+
1043+
1044+
// Fast Init
1045+
let a: HashSet<i32> = [1, 2, 3].iter().cloned().collect();
1046+
let b: HashSet<i32> = [4, 2, 3, 4].iter().cloned().collect();
1047+
1048+
// Can be seen as `a - b`.
1049+
// x typed as &
1050+
for x in a.difference(&b) {
1051+
// println!("{}", x); // Print 1
1052+
}
1053+
1054+
let diff: HashSet<i32> = a.difference(&b).cloned().collect();
1055+
assert_eq!(diff, [1].iter().cloned().collect());
1056+
1057+
// Note that difference is not symmetric,
1058+
// and `b - a` means something else:
1059+
// no cloned to get a set of reference.
1060+
let diff: HashSet<&i32> = b.difference(&a).collect();
1061+
assert_eq!(diff, [4].iter().collect());
1062+
1063+
let intersection: HashSet<i32> = a.intersection(&b).cloned().collect();
1064+
assert_eq!(intersection, [2,3].iter().cloned().collect());
1065+
1066+
let union: HashSet<i32> = a.union(&b).cloned().collect();
1067+
assert_eq!(union, [1,2,3,4].iter().cloned().collect());
1068+
assert!(!a.is_subset(&b));
1069+
assert!(!a.is_superset(&b));
1070+
10501071
}
10511072
}
10521073
struct Util(i32, i32);
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* [330] Patching Array
3+
*
4+
* Given a sorted integer array nums and an integer n, add/patch elements to the array such that any number in the range [1, n] inclusive can be formed by the sum of some elements in the array.
5+
* Return the minimum number of patches required.
6+
*
7+
* Example 1:
8+
*
9+
* Input: nums = [1,3], n = 6
10+
* Output: 1
11+
* Explanation:
12+
* Combinations of nums are [1], [3], [1,3], which form possible sums of: 1, 3, 4.
13+
* Now if we add/patch 2 to nums, the combinations are: [1], [2], [3], [1,3], [2,3], [1,2,3].
14+
* Possible sums are 1, 2, 3, 4, 5, 6, which now covers the range [1, 6].
15+
* So we only need 1 patch.
16+
*
17+
* Example 2:
18+
*
19+
* Input: nums = [1,5,10], n = 20
20+
* Output: 2
21+
* Explanation: The two patches can be [2, 4].
22+
*
23+
* Example 3:
24+
*
25+
* Input: nums = [1,2,2], n = 5
26+
* Output: 0
27+
*
28+
*
29+
* Constraints:
30+
*
31+
* 1 <= nums.length <= 1000
32+
* 1 <= nums[i] <= 10^4
33+
* nums is sorted in ascending order.
34+
* 1 <= n <= 2^31 - 1
35+
*
36+
*/
37+
pub struct Solution {}
38+
39+
// problem: https://leetcode.com/problems/patching-array/
40+
// discuss: https://leetcode.com/problems/patching-array/discuss/?currentPage=1&orderBy=most_votes&query=
41+
42+
// submission codes start here
43+
44+
impl Solution {
45+
pub fn min_patches(nums: Vec<i32>, n: i32) -> i32 {
46+
let mut miss_count : i32 = 0;
47+
let mut next_miss : i64 = 1;
48+
let n = n as i64;
49+
let mut i : usize = 0;
50+
while next_miss <= n {
51+
if i < nums.len() && nums[i] as i64 <= next_miss {
52+
next_miss += nums[i] as i64;
53+
i+=1;
54+
} else {
55+
miss_count += 1;
56+
next_miss *= 2;
57+
}
58+
}
59+
miss_count
60+
}
61+
}
62+
63+
// submission codes end
64+
65+
#[cfg(test)]
66+
mod tests {
67+
use super::*;
68+
69+
#[test]
70+
fn test_330() {
71+
assert_eq!(Solution::min_patches(vec![1,3], 6), 1);
72+
assert_eq!(Solution::min_patches(vec![1,5,10], 20), 2);
73+
}
74+
}

src/problem/p0335_self_crossing.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* [335] Self Crossing
3+
*
4+
* You are given an array of integers distance.
5+
* You start at point (0,0) on an X-Y plane and you move distance[0] meters to the north, then distance[1] meters to the west, distance[2] meters to the south, distance[3] meters to the east, and so on. In other words, after each move, your direction changes counter-clockwise.
6+
* Return true if your path crosses itself, and false if it does not.
7+
*
8+
* Example 1:
9+
* <img alt="" src="https://assets.leetcode.com/uploads/2021/03/14/selfcross1-plane.jpg" style="width: 400px; height: 435px;" />
10+
* Input: distance = [2,1,1,2]
11+
* Output: true
12+
*
13+
* Example 2:
14+
* <img alt="" src="https://assets.leetcode.com/uploads/2021/03/14/selfcross2-plane.jpg" style="width: 400px; height: 435px;" />
15+
* Input: distance = [1,2,3,4]
16+
* Output: false
17+
*
18+
* Example 3:
19+
* <img alt="" src="https://assets.leetcode.com/uploads/2021/03/14/selfcross3-plane.jpg" style="width: 400px; height: 435px;" />
20+
* Input: distance = [1,1,1,1]
21+
* Output: true
22+
*
23+
*
24+
* Constraints:
25+
*
26+
* 1 <= distance.length <= 500
27+
* 1 <= distance[i] <= 500
28+
*
29+
*
30+
* Follow up: Could you write a one-pass algorithm with O(1) extra space?
31+
*
32+
*/
33+
pub struct Solution {}
34+
35+
// problem: https://leetcode.com/problems/self-crossing/
36+
// discuss: https://leetcode.com/problems/self-crossing/discuss/?currentPage=1&orderBy=most_votes&query=
37+
38+
// submission codes start here
39+
40+
impl Solution {
41+
pub fn is_self_crossing(d: Vec<i32>) -> bool {
42+
for i in (0..d.len()) {
43+
if 3 <= i && d[i-2] <= d[i] && d[i-1] <= d[i-3] {
44+
return true;
45+
}
46+
47+
if 4 <= i && d[i-1] == d[i-3] && d[i] + d[i-4] >= d[i-2] {
48+
return true;
49+
}
50+
51+
if 5 <= i && d[i-2] > d[i-4] && d[i-4]+d[i]>=d[i-2] && d[i-3]>d[i-1] && d[i-5]+d[i-1]>=d[i-3]{
52+
return true;
53+
}
54+
55+
}
56+
false
57+
}
58+
}
59+
60+
// submission codes end
61+
62+
#[cfg(test)]
63+
mod tests {
64+
use super::*;
65+
66+
#[test]
67+
fn test_335() {
68+
assert!(Solution::is_self_crossing(vec![2,1,1,2]));
69+
assert!(!Solution::is_self_crossing(vec![1,2,3,4]));
70+
assert!(Solution::is_self_crossing(vec![1,1,1,1]));
71+
}
72+
}

0 commit comments

Comments
 (0)