Skip to content

Commit b69ac19

Browse files
committed
163&642&947
1 parent 896a4ae commit b69ac19

File tree

4 files changed

+310
-0
lines changed

4 files changed

+310
-0
lines changed

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ mod prob_144;
8787
mod prob_149;
8888
mod prob_159;
8989
mod prob_161;
90+
mod prob_163;
9091
mod prob_166;
9192
mod prob_173;
9293
mod prob_174;
@@ -287,6 +288,7 @@ mod prob_632;
287288
mod prob_636;
288289
mod prob_637;
289290
mod prob_640;
291+
mod prob_642;
290292
mod prob_647;
291293
mod prob_648;
292294
mod prob_652;
@@ -314,6 +316,7 @@ mod prob_844;
314316
mod prob_887;
315317
mod prob_932;
316318
mod prob_946;
319+
mod prob_947;
317320
mod prob_973;
318321
mod prob_974;
319322
mod prob_975;

src/prob_163.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
impl Solution {
2+
pub fn find_missing_ranges(nums: Vec<i32>, lower: i32, upper: i32) -> Vec<String> {
3+
let n = nums.len();
4+
if n == 0 {
5+
if lower == upper {
6+
return vec![lower.to_string()];
7+
} else {
8+
return vec![format!("{}->{}", lower, upper)];
9+
}
10+
}
11+
let mut ans = vec![];
12+
if nums[0] > lower {
13+
ans.push((lower, nums[0]-1));
14+
}
15+
let mut i = 0;
16+
for i in 0..n-1 {
17+
if let Some(delta) = nums[i+1].checked_sub(nums[i]) {
18+
if delta > 1 {
19+
ans.push((nums[i]+1, nums[i+1]-1));
20+
}
21+
} else {
22+
ans.push((nums[i]+1, nums[i+1]-1));
23+
}
24+
}
25+
if nums[n-1] < upper {
26+
ans.push((nums[n-1]+1, upper));
27+
}
28+
ans.into_iter().map(|(x,y)| {
29+
if x == y {
30+
x.to_string()
31+
} else {
32+
format!("{}->{}",x,y)
33+
}
34+
}).collect()
35+
}
36+
}
37+
38+
struct Solution;
39+
40+
#[cfg(test)]
41+
mod tests {
42+
use super::Solution;
43+
44+
#[test]
45+
fn test_find_missing_ranges() {
46+
let test_cases = vec![
47+
(vec![-2147483648,2147483647],-2147483648,2147483647,vec!["-2147483647->2147483646"]),
48+
(vec![0, 1, 3, 50, 75], 0, 99, vec!["2", "4->49", "51->74", "76->99"]),
49+
];
50+
for (nums, lower, upper, expect) in test_cases {
51+
assert_eq!(Solution::find_missing_ranges(nums.clone(), lower, upper), expect, "nums: {:?}, lower: {}, upper: {}", nums, lower, upper);
52+
}
53+
}
54+
}

src/prob_642.rs

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
use std::collections::HashMap;
2+
3+
struct AutocompleteSystem {
4+
content: Vec<u8>,
5+
trie: Trie,
6+
hash: HashMap<String, i32>,
7+
empty: bool,
8+
}
9+
10+
impl AutocompleteSystem {
11+
12+
fn new(sentences: Vec<String>, times: Vec<i32>) -> Self {
13+
let mut hash = HashMap::new();
14+
let mut trie = Trie::new();
15+
for (s,t) in sentences.into_iter().zip(times) {
16+
trie.insert(s.as_bytes());
17+
hash.insert(s, t);
18+
}
19+
Self{
20+
content: vec![],
21+
trie,
22+
hash,
23+
empty: false,
24+
}
25+
}
26+
27+
fn input(&mut self, c: char) -> Vec<String> {
28+
let mut ans = vec![];
29+
if c == '#' {
30+
*self.hash.entry(unsafe {std::str::from_utf8_unchecked(&self.content).to_string()}).or_insert(0) += 1;
31+
self.empty = false;
32+
self.trie.insert(&self.content);
33+
self.content.clear();
34+
return vec![];
35+
} else {
36+
self.content.push(c as u8);
37+
if self.empty {
38+
return vec![];
39+
}
40+
ans = self.trie.find_prefix(&self.content, 0)
41+
}
42+
if ans.is_empty() {
43+
self.empty = true;
44+
}
45+
if self.empty {
46+
return vec![];
47+
}
48+
ans.sort_by(|a,b| {
49+
let ta = *self.hash.get(a).unwrap();
50+
let tb = *self.hash.get(b).unwrap();
51+
if ta == tb {
52+
a.cmp(b)
53+
} else {
54+
tb.cmp(&ta)
55+
}
56+
});
57+
58+
(0..ans.len().min(3)).into_iter().map(|i| ans[i].clone()).collect()
59+
}
60+
}
61+
62+
struct Trie {
63+
data: HashMap<u8, Option<Box<Trie>>>,
64+
term: bool,
65+
}
66+
67+
impl Trie {
68+
fn new() -> Self {
69+
Self {
70+
data: HashMap::new(),
71+
term: false,
72+
}
73+
}
74+
fn insert(&mut self, s: &[u8]) {
75+
if s.is_empty() {
76+
return;
77+
}
78+
if let Some(node) = self.data.get_mut(&s[0]) {
79+
if s.len() == 1 {
80+
node.as_mut().unwrap().term = true;
81+
return;
82+
}
83+
node.as_mut().unwrap().insert(&s[1..]);
84+
} else {
85+
let mut node = Self::new();
86+
if s.len() == 1 {
87+
node.term = true;
88+
} else {
89+
node.insert(&s[1..]);
90+
}
91+
self.data.insert(s[0], Some(Box::new(node)));
92+
}
93+
}
94+
fn find_prefix(&self, s: &[u8], i: usize) -> Vec<String> {
95+
if i == s.len() {
96+
let mut prefix = Vec::from(s);
97+
return self.find_all(&mut prefix);
98+
}
99+
if let Some(node) = self.data.get(&s[i]) {
100+
return node.as_ref().unwrap().find_prefix(s, i+1);
101+
}
102+
return vec![]
103+
}
104+
fn find_all(&self, prefix: &mut Vec<u8>) -> Vec<String> {
105+
let mut ans = vec![];
106+
if self.term {
107+
ans.push(unsafe{std::str::from_utf8_unchecked(&prefix).to_string()});
108+
}
109+
for (&c, node) in self.data.iter() {
110+
prefix.push(c);
111+
let mut t = node.as_ref().unwrap().find_all(prefix);
112+
if !t.is_empty() {
113+
ans.append(&mut t);
114+
}
115+
prefix.pop();
116+
}
117+
ans
118+
}
119+
}
120+
121+
#[cfg(test)]
122+
mod tests {
123+
use super::AutocompleteSystem;
124+
125+
#[test]
126+
fn test_input() {
127+
let test_cases = vec![
128+
(
129+
vec!["i love you", "island", "ironman", "i love leetcode"],
130+
vec![5,3,2,2],
131+
vec![
132+
('i', vec!["i love you", "island","i love leetcode"]),
133+
(' ', vec!["i love you","i love leetcode"]),
134+
('a', vec![]),
135+
('#', vec![]),
136+
('i', vec!["i love you", "island","i love leetcode"]),
137+
(' ', vec!["i love you","i love leetcode", "i a"]),
138+
('a', vec!["i a"]),
139+
('#', vec![]),
140+
('i', vec!["i love you", "island","i a"]),
141+
(' ', vec!["i love you","i a", "i love leetcode"]),
142+
('a', vec!["i a"]),
143+
('#', vec![]),
144+
],
145+
),
146+
(
147+
vec!["i love you", "island", "ironman", "i love leetcode"],
148+
vec![5,3,2,2],
149+
vec![
150+
('i', vec!["i love you", "island","i love leetcode"]),
151+
(' ', vec!["i love you","i love leetcode"]),
152+
('l', vec!["i love you","i love leetcode"]),
153+
('o', vec!["i love you","i love leetcode"]),
154+
('v', vec!["i love you","i love leetcode"]),
155+
('e', vec!["i love you","i love leetcode"]),
156+
(' ', vec!["i love you","i love leetcode"]),
157+
('l', vec!["i love leetcode"]),
158+
('c', vec![]),
159+
('#', vec![]),
160+
('i', vec!["i love you", "island","i love leetcode"]),
161+
(' ', vec!["i love you","i love leetcode", "i love lc"]),
162+
('l', vec!["i love you","i love leetcode", "i love lc"]),
163+
('o', vec!["i love you","i love leetcode", "i love lc"]),
164+
('v', vec!["i love you","i love leetcode", "i love lc"]),
165+
('e', vec!["i love you","i love leetcode", "i love lc"]),
166+
(' ', vec!["i love you","i love leetcode", "i love lc"]),
167+
('y', vec!["i love you"]),
168+
('#', vec![]),
169+
],
170+
),
171+
];
172+
for (s, t, tc) in test_cases {
173+
let mut obj = AutocompleteSystem::new(s.iter().map(|v| v.to_string()).collect(), t);
174+
for (c, expect) in tc {
175+
assert_eq!(obj.input(c), expect, "c:{}", c);
176+
}
177+
}
178+
}
179+
}

src/prob_947.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
use std::collections::HashSet;
2+
3+
struct DSU {
4+
parent: Vec<usize>
5+
}
6+
7+
impl DSU {
8+
fn new(n: usize, step: usize) -> Self {
9+
let mut parent = vec![0; n+step];
10+
for i in 0..n+step {
11+
parent[i] = i;
12+
}
13+
Self{
14+
parent,
15+
}
16+
}
17+
fn get_parent(&mut self, x: usize) -> usize {
18+
if self.parent[x] == x {
19+
return x;
20+
}
21+
let p = self.get_parent(self.parent[x]);
22+
self.parent[x] = p;
23+
p
24+
}
25+
fn union(&mut self, x: usize, y: usize) {
26+
let px = self.get_parent(x);
27+
let py = self.get_parent(y);
28+
self.parent[py] = px;
29+
}
30+
}
31+
32+
impl Solution {
33+
pub fn remove_stones(stones: Vec<Vec<i32>>) -> i32 {
34+
let n = stones.len();
35+
if n == 1 {
36+
return 0;
37+
}
38+
let mut t = DSU::new(10000, 10000);
39+
for stone in &stones {
40+
let (x,y) = (stone[0], stone[1]+10000);
41+
t.union(x as usize,y as usize);
42+
}
43+
let mut set = HashSet::new();
44+
for stone in &stones {
45+
let (x,y) = (stone[0] as usize, stone[1] as usize+10000);
46+
if t.get_parent(x) == x {
47+
set.insert(x);
48+
} else if t.get_parent(y) == y {
49+
set.insert(y);
50+
}
51+
}
52+
(n-set.len()) as i32
53+
}
54+
}
55+
56+
struct Solution;
57+
58+
#[cfg(test)]
59+
mod tests {
60+
use super::Solution;
61+
62+
#[test]
63+
fn test_remove_stones() {
64+
let test_cases = vec![
65+
(vec![[0,1],[1,0]], 0),
66+
(vec![[0,0]], 0),
67+
(vec![[0,0],[0,1],[1,0],[1,2],[2,1],[2,2]], 5),
68+
(vec![[0,0],[0,2],[1,1],[2,0],[2,2]], 3),
69+
];
70+
for (stones, expect) in test_cases {
71+
assert_eq!(Solution::remove_stones(stones.iter().map(|v| vec![v[0],v[1]]).collect()), expect, "stones: {:?}", stones);
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)