Skip to content

Commit 6f94a60

Browse files
committed
solve 337, 347, 357, 368, 373
1 parent 696f0a3 commit 6f94a60

6 files changed

+380
-0
lines changed

src/solution/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,7 @@ mod s0322_coin_change;
273273
mod s0328_odd_even_linked_list;
274274
mod s0331_verify_preorder_serialization_of_a_binary_tree;
275275
mod s0337_house_robber_iii;
276+
mod s0347_top_k_frequent_elements;
277+
mod s0357_count_numbers_with_unique_digits;
278+
mod s0368_largest_divisible_subset;
279+
mod s0373_find_k_pairs_with_smallest_sums;
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/**
2+
* [337] House Robber III
3+
*
4+
* The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night.
5+
*
6+
* Determine the maximum amount of money the thief can rob tonight without alerting the police.
7+
*
8+
* Example 1:
9+
*
10+
*
11+
* Input: [3,2,3,null,3,null,1]
12+
*
13+
* <font color="red">3</font>
14+
* / \
15+
* 2 3
16+
* \ \
17+
* <font color="red">3 1
18+
* </font>
19+
* Output: 7
20+
* Explanation: Maximum amount of money the thief can rob = <font color="red" style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";">3</font><span style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";"> + </span><font color="red" style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";">3</font><span style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";"> + </span><font color="red" style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";">1</font><span style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";"> = </span><b style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";">7<span style="font-family: sans-serif, Arial, Verdana, "Trebuchet MS";">.</span>
21+
*
22+
* Example 2:
23+
*
24+
*
25+
* Input: [3,4,5,1,3,null,1]
26+
*
27+
* 3
28+
* / \
29+
* <font color="red">4</font> <font color="red">5</font>
30+
* / \ \
31+
* 1 3 1
32+
*
33+
* Output: 9
34+
* Explanation: Maximum amount of money the thief can rob = <font color="red">4</font> + <font color="red">5</font> = 9.
35+
*
36+
*/
37+
pub struct Solution {}
38+
use crate::util::tree::{to_tree, TreeNode};
39+
40+
// submission codes start here
41+
42+
// Definition for a binary tree node.
43+
// #[derive(Debug, PartialEq, Eq)]
44+
// pub struct TreeNode {
45+
// pub val: i32,
46+
// pub left: Option<Rc<RefCell<TreeNode>>>,
47+
// pub right: Option<Rc<RefCell<TreeNode>>>,
48+
// }
49+
//
50+
// impl TreeNode {
51+
// #[inline]
52+
// pub fn new(val: i32) -> Self {
53+
// TreeNode {
54+
// val,
55+
// left: None,
56+
// right: None
57+
// }
58+
// }
59+
// }
60+
use std::cell::RefCell;
61+
use std::rc::Rc;
62+
impl Solution {
63+
pub fn rob(root: Option<Rc<RefCell<TreeNode>>>) -> i32 {
64+
if root.is_none() {
65+
return 0;
66+
}
67+
let left = root.as_ref().unwrap().borrow().left.clone();
68+
let right = root.as_ref().unwrap().borrow().right.clone();
69+
if left.is_none() && right.is_none() {
70+
return root.unwrap().borrow().val;
71+
}
72+
let (left_left, left_right) = if left.is_none() {
73+
(None, None)
74+
} else {
75+
(
76+
left.as_ref().unwrap().borrow().left.clone(),
77+
left.as_ref().unwrap().borrow().right.clone(),
78+
)
79+
};
80+
81+
let (right_left, right_right) = if right.is_none() {
82+
(None, None)
83+
} else {
84+
(
85+
right.as_ref().unwrap().borrow().left.clone(),
86+
right.as_ref().unwrap().borrow().right.clone(),
87+
)
88+
};
89+
90+
(root.unwrap().borrow().val
91+
+ Self::rob(left_left)
92+
+ Self::rob(left_right)
93+
+ Self::rob(right_left)
94+
+ Self::rob(right_right))
95+
.max(Self::rob(left) + Self::rob(right))
96+
}
97+
}
98+
99+
// submission codes end
100+
101+
#[cfg(test)]
102+
mod tests {
103+
use super::*;
104+
105+
#[test]
106+
fn test_337() {}
107+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* [347] Top K Frequent Elements
3+
*
4+
* Given a non-empty array of integers, return the k most frequent elements.
5+
*
6+
* Example 1:
7+
*
8+
*
9+
* Input: nums = <span id="example-input-1-1">[1,1,1,2,2,3]</span>, k = <span id="example-input-1-2">2</span>
10+
* Output: <span id="example-output-1">[1,2]</span>
11+
*
12+
*
13+
* <div>
14+
* Example 2:
15+
*
16+
*
17+
* Input: nums = <span id="example-input-2-1">[1]</span>, k = <span id="example-input-2-2">1</span>
18+
* Output: <span id="example-output-2">[1]</span>
19+
* </div>
20+
*
21+
* Note:
22+
*
23+
*
24+
* You may assume k is always valid, 1 &le; k &le; number of unique elements.
25+
* Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
26+
*
27+
*
28+
*/
29+
pub struct Solution {}
30+
31+
// submission codes start here
32+
33+
impl Solution {
34+
pub fn top_k_frequent(nums: Vec<i32>, k: i32) -> Vec<i32> {
35+
use std::collections::HashMap;
36+
let mut map = HashMap::new();
37+
nums.iter()
38+
.map(|num| *map.entry(*num).or_insert(0) += 1)
39+
.count();
40+
let mut nums: Vec<i32> = map.keys().map(|num| *num).collect();
41+
nums.sort_by_key(|num| -*map.get(num).unwrap());
42+
nums[0..k as usize].to_vec()
43+
}
44+
}
45+
46+
// submission codes end
47+
48+
#[cfg(test)]
49+
mod tests {
50+
use super::*;
51+
52+
#[test]
53+
fn test_347() {}
54+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* [357] Count Numbers with Unique Digits
3+
*
4+
* Given a non-negative integer n, count all numbers with unique digits, x, where 0 &le; x < 10^n.
5+
*
6+
* <div>
7+
* Example:
8+
*
9+
*
10+
* Input: <span id="example-input-1-1">2</span>
11+
* Output: <span id="example-output-1">91
12+
* Explanation: </span>The answer should be the total numbers in the range of 0 &le; x < 100,
13+
* excluding 11,22,33,44,55,66,77,88,99
14+
*
15+
* </div>
16+
*/
17+
pub struct Solution {}
18+
19+
// submission codes start here
20+
21+
impl Solution {
22+
pub fn count_numbers_with_unique_digits(n: i32) -> i32 {
23+
if n == 0 {
24+
return 0;
25+
}
26+
if n == 1 {
27+
return 10;
28+
}
29+
if n == 2 {
30+
return 91;
31+
}
32+
let mut dp = vec![0; n as usize + 1];
33+
dp[1] = 10;
34+
dp[2] = 91;
35+
for i in 3..(n + 1) {
36+
let mut curr = 9;
37+
let mut remain = 9;
38+
for _ in 0..(i - 1) {
39+
curr *= remain;
40+
remain -= 1;
41+
}
42+
dp[i as usize] = dp[i as usize - 1] + curr;
43+
}
44+
dp[n as usize]
45+
}
46+
}
47+
48+
// submission codes end
49+
50+
#[cfg(test)]
51+
mod tests {
52+
use super::*;
53+
54+
#[test]
55+
fn test_357() {}
56+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* [368] Largest Divisible Subset
3+
*
4+
* Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of elements in this subset satisfies:
5+
*
6+
* Si % Sj = 0 or Sj % Si = 0.
7+
*
8+
* If there are multiple solutions, return any subset is fine.
9+
*
10+
* Example 1:
11+
*
12+
* <div>
13+
*
14+
* Input: <span id="example-input-1-1">[1,2,3]</span>
15+
* Output: <span id="example-output-1">[1,2] </span>(of course, [1,3] will also be ok)
16+
*
17+
*
18+
* <div>
19+
* Example 2:
20+
*
21+
*
22+
* Input: <span id="example-input-2-1">[1,2,4,8]</span>
23+
* Output: <span id="example-output-2">[1,2,4,8]</span>
24+
*
25+
* </div>
26+
* </div>
27+
*/
28+
pub struct Solution {}
29+
30+
// submission codes start here
31+
32+
impl Solution {
33+
pub fn largest_divisible_subset(nums: Vec<i32>) -> Vec<i32> {
34+
let mut nums = nums;
35+
nums.sort();
36+
let mut prev_indices: Vec<i32> = vec![-1; nums.len()];
37+
let mut dp = vec![1; nums.len()];
38+
let mut max_count = 0;
39+
let mut max_index: i32 = -1;
40+
for i in 0..nums.len() {
41+
for j in (0..i).rev() {
42+
if nums[i] % nums[j] == 0 && dp[j] + 1 > dp[i] {
43+
dp[i] = dp[j] + 1;
44+
prev_indices[i] = j as i32;
45+
}
46+
}
47+
if dp[i] > max_count {
48+
max_count = dp[i];
49+
max_index = i as i32;
50+
}
51+
}
52+
let mut ret = vec![];
53+
while max_index != -1 {
54+
ret.push(nums[max_index as usize]);
55+
max_index = prev_indices[max_index as usize];
56+
}
57+
ret
58+
}
59+
}
60+
61+
// submission codes end
62+
63+
#[cfg(test)]
64+
mod tests {
65+
use super::*;
66+
67+
#[test]
68+
fn test_368() {
69+
println!("{:?}", Solution::largest_divisible_subset(vec![1, 2, 3]));
70+
}
71+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/**
2+
* [373] Find K Pairs with Smallest Sums
3+
*
4+
* You are given two integer arrays nums1 and nums2 sorted in ascending order and an integer k.
5+
*
6+
* Define a pair (u,v) which consists of one element from the first array and one element from the second array.
7+
*
8+
* Find the k pairs (u1,v1),(u2,v2) ...(uk,vk) with the smallest sums.
9+
*
10+
* Example 1:
11+
*
12+
*
13+
* Input: nums1 = <span id="example-input-1-1">[1,7,11]</span>, nums2 = <span id="example-input-1-2">[2,4,6]</span>, k = <span id="example-input-1-3">3</span>
14+
* Output: <span id="example-output-1">[[1,2],[1,4],[1,6]]
15+
* Explanation: </span>The first 3 pairs are returned from the sequence:
16+
* [1,2],[1,4],[1,6],[7,2],[7,4],[11,2],[7,6],[11,4],[11,6]
17+
*
18+
* Example 2:
19+
*
20+
*
21+
* Input: nums1 = [1,1,2], nums2 = [1,2,3], k = 2
22+
* Output: [1,1],[1,1]<span>
23+
* Explanation: </span>The first 2 pairs are returned from the sequence:
24+
* [1,1],[1,1],[1,2],[2,1],[1,2],[2,2],[1,3],[1,3],[2,3]
25+
*
26+
* Example 3:
27+
*
28+
*
29+
* Input: nums1 = [1,2], nums2 = [3], k = 3
30+
* Output: [1,3],[2,3]<span>
31+
* Explanation: </span>All possible pairs are returned from the sequence: [1,3],[2,3]
32+
*
33+
*
34+
*/
35+
pub struct Solution {}
36+
37+
// submission codes start here
38+
39+
impl Solution {
40+
pub fn k_smallest_pairs(nums1: Vec<i32>, nums2: Vec<i32>, k: i32) -> Vec<Vec<i32>> {
41+
// use a max heap
42+
use std::collections::BinaryHeap;
43+
let k = k as usize;
44+
let mut max_heap = BinaryHeap::with_capacity(k);
45+
for num1 in &nums1 {
46+
for num2 in &nums2 {
47+
let sum = *num1 + *num2;
48+
if max_heap.len() < k {
49+
max_heap.push(sum);
50+
} else {
51+
let mut top = max_heap.peek_mut().unwrap();
52+
if sum < *top {
53+
*top = sum;
54+
}
55+
}
56+
}
57+
}
58+
let mut ret = vec![];
59+
let top = max_heap.peek();
60+
if top.is_none() {
61+
return ret;
62+
}
63+
let top = *top.unwrap();
64+
for num1 in &nums1 {
65+
for num2 in &nums2 {
66+
let sum = *num1 + *num2;
67+
if sum <= top {
68+
ret.push(vec![*num1, *num2]);
69+
}
70+
}
71+
}
72+
ret.sort_by_key(|v| v[0] + v[1]);
73+
if ret.len() > k {
74+
ret.split_off(k);
75+
}
76+
ret
77+
}
78+
}
79+
80+
// submission codes end
81+
82+
#[cfg(test)]
83+
mod tests {
84+
use super::*;
85+
86+
#[test]
87+
fn test_373() {}
88+
}

0 commit comments

Comments
 (0)