some more problems
This commit is contained in:
parent
3cc60d0431
commit
4a14268528
|
@ -0,0 +1,42 @@
|
|||
package main
|
||||
|
||||
type TreeNode struct {
|
||||
Val int
|
||||
Left *TreeNode
|
||||
Right *TreeNode
|
||||
}
|
||||
|
||||
/**
|
||||
* Definition for a binary tree node.
|
||||
* type TreeNode struct {
|
||||
* Val int
|
||||
* Left *TreeNode
|
||||
* Right *TreeNode
|
||||
* }
|
||||
*/
|
||||
func minCameraCover(root *TreeNode) int {
|
||||
covered := map[*TreeNode]bool{
|
||||
nil: true,
|
||||
}
|
||||
return dfs(root, nil, covered)
|
||||
}
|
||||
|
||||
func dfs(node, parent *TreeNode, covered map[*TreeNode]bool) int {
|
||||
if node != nil {
|
||||
out := dfs(node.Left, node, covered)
|
||||
out += dfs(node.Right, node, covered)
|
||||
|
||||
_, nc := covered[node]
|
||||
_, lc := covered[node.Left]
|
||||
_, rc := covered[node.Right]
|
||||
if parent == nil && !nc || !lc || !rc {
|
||||
covered[node] = true
|
||||
covered[parent] = true
|
||||
covered[node.Left] = true
|
||||
covered[node.Right] = true
|
||||
return out + 1
|
||||
}
|
||||
return out
|
||||
}
|
||||
return 0
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
struct Solution{}
|
||||
// Copied this from the solutions tab pretty much since I couldn't
|
||||
// solve the problem myself in under O(n^2) (Time Limit Exceeded)
|
||||
// Good learning problem though
|
||||
impl Solution {
|
||||
pub fn min_distance(word1: String, word2: String) -> i32 {
|
||||
let mut dp = vec![0; word2.len() + 1];
|
||||
let (w1, w2) = (word1.chars().collect::<Vec<_>>(), word2.chars().collect::<Vec<_>>());
|
||||
for i in 0..word1.len() + 1 {
|
||||
let mut tmp = vec![0; word2.len() + 1];
|
||||
for j in 0..word2.len() + 1 {
|
||||
if (i == 0 || j == 0) {
|
||||
tmp[j] = i + j;
|
||||
} else if (w1[i - 1] == w2[j - 1]) {
|
||||
tmp[j] = dp[j - 1];
|
||||
} else {
|
||||
tmp[j] = 1 + dp[j].min(tmp[j - 1]);
|
||||
}
|
||||
}
|
||||
dp = tmp;
|
||||
}
|
||||
dp[word2.len()] as i32
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", Solution::min_distance(String::from("ebvivhpfxoptspwianmuhmkmbhxkqbrbgpfwpfcjixzhsjmtsgrzfshvkrvoxvjpmmsrojnpgzqdyofvicscopak"), String::from("vxoumkmxbpcixzhtrfhxmnzqyvisp")));
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
class Solution:
|
||||
def longestPalindrome(self, s: str) -> str:
|
||||
max_palindrome = ""
|
||||
for idx in range(len(s)):
|
||||
l, r, odd, even = idx, idx, True, True
|
||||
while odd or even:
|
||||
if odd:
|
||||
if r == len(s) or s[l] != s[r]:
|
||||
odd = False
|
||||
if r - l - 1 > len(max_palindrome):
|
||||
max_palindrome = s[l + 1:r]
|
||||
if even:
|
||||
if r == len(s) - 1 or s[l] != s[r + 1]:
|
||||
even = False
|
||||
if r - l > len(max_palindrome):
|
||||
max_palindrome = s[l + 1:r + 1]
|
||||
if l == 0:
|
||||
if even and r - l + 2 > len(max_palindrome):
|
||||
max_palindrome = s[l:r + 2]
|
||||
elif odd and r - l + 1 > len(max_palindrome):
|
||||
max_palindrome = s[l:r + 1]
|
||||
break
|
||||
l -= 1
|
||||
r += 1
|
||||
return max_palindrome
|
|
@ -0,0 +1,38 @@
|
|||
impl Solution {
|
||||
pub fn longest_palindrome(s: String) -> String {
|
||||
let mut max = "";
|
||||
let bytes = s.as_bytes();
|
||||
for idx in 0..s.len() {
|
||||
let (mut l, mut r, mut odd, mut even) = (idx, idx, true, true);
|
||||
while odd || even {
|
||||
if odd {
|
||||
if r == s.len() || bytes[l] != bytes[r] {
|
||||
odd = false;
|
||||
if r - l - 1 > max.len() {
|
||||
max = s.get(l + 1..r).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
if even {
|
||||
if r == s.len() - 1 || bytes[l] != bytes[r + 1] {
|
||||
even = false;
|
||||
if r - l > max.len() {
|
||||
max = s.get(l + 1..r + 1).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
if l == 0 {
|
||||
if even && r - l + 2 > max.len() {
|
||||
max = s.get(l..r + 2).unwrap();
|
||||
} else if odd && r - l + 1 > max.len() {
|
||||
max = s.get(l..r + 1).unwrap();
|
||||
}
|
||||
break;
|
||||
}
|
||||
l -= 1;
|
||||
r += 1;
|
||||
}
|
||||
}
|
||||
max.to_string()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
impl Solution {
|
||||
pub fn get_max_chain_len(from: &Vec<Vec<usize>>, memos: &mut Vec<i32>, start: usize) -> i32 {
|
||||
let memo_val = *memos.get(start).unwrap_or(&-1);
|
||||
if memo_val != -1 {
|
||||
return memo_val;
|
||||
}
|
||||
let max_len = from.get(start)
|
||||
.unwrap()
|
||||
.iter()
|
||||
.map(|&next| Solution::get_max_chain_len(from, memos, next))
|
||||
.max()
|
||||
.unwrap_or(0) + 1;
|
||||
memos[start] = max_len;
|
||||
max_len
|
||||
}
|
||||
#[inline]
|
||||
pub fn is_predecessor(word: &String, of_word: &String) -> bool {
|
||||
let mut skipped = false;
|
||||
let mut oi = of_word.bytes();
|
||||
of_word.len() == word.len() + 1 && word.bytes()
|
||||
.all(|chr| {
|
||||
if chr == oi.next().unwrap() { // Before extra character
|
||||
true
|
||||
} else if !skipped && chr == oi.next().unwrap() { // Extra character, skipped ensures this can only run once
|
||||
skipped = true;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
pub fn longest_str_chain(words: Vec<String>) -> i32 {
|
||||
let (mut from, mut to) = (vec![vec![]; words.len()], vec![true; words.len()]);
|
||||
for (idx1, w1) in words.iter().enumerate() {
|
||||
for (idx2, w2) in words.iter().enumerate() {
|
||||
if Solution::is_predecessor(w1, w2) {
|
||||
from[idx1].push(idx2);
|
||||
to[idx2] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut memos = vec![-1; words.len()];
|
||||
to.into_iter()
|
||||
.enumerate()
|
||||
.filter_map(|(to, froms)| {
|
||||
if froms {
|
||||
Some(Solution::get_max_chain_len(&from, &mut memos, to))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.max()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package main
|
||||
|
||||
type StringMap struct {
|
||||
Map SubStringMap
|
||||
}
|
||||
|
||||
func NewStringMap() *StringMap {
|
||||
return &StringMap{
|
||||
Map: map[byte]*StringMap{},
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *StringMap) CombineAllSubStrings(prefix string, rev bool) []string {
|
||||
if len(sm.Map) == 0 {
|
||||
return []string{prefix}
|
||||
}
|
||||
out := []string{}
|
||||
for chr, Map := range sm.Map {
|
||||
if rev {
|
||||
out = append(out, Map.CombineAllSubStrings(string(chr)+prefix, rev)...)
|
||||
} else {
|
||||
out = append(out, Map.CombineAllSubStrings(prefix+string(chr), rev)...)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func (sm *StringMap) Add(word string, rev bool) {
|
||||
if len(word) == 0 {
|
||||
return
|
||||
}
|
||||
take := 0
|
||||
if rev {
|
||||
take = len(word) - 1
|
||||
}
|
||||
sub, ok := sm.Map[word[take]]
|
||||
if !ok {
|
||||
sub = NewStringMap()
|
||||
sm.Map[word[take]] = sub
|
||||
}
|
||||
if rev {
|
||||
sub.Add(word[:take], rev)
|
||||
} else {
|
||||
sub.Add(word[1:], rev)
|
||||
}
|
||||
}
|
||||
|
||||
type SubStringMap = map[byte]*StringMap
|
||||
|
||||
type WordFilter struct {
|
||||
Prefixes *StringMap
|
||||
Suffixes *StringMap
|
||||
Words map[string]int
|
||||
}
|
||||
|
||||
func Constructor(words []string) WordFilter {
|
||||
Prefixes := NewStringMap()
|
||||
Suffixes := NewStringMap()
|
||||
Words := map[string]int{}
|
||||
|
||||
for idx, word := range words {
|
||||
Words[word] = idx
|
||||
Prefixes.Add(word, false)
|
||||
Suffixes.Add(word, true)
|
||||
}
|
||||
return WordFilter{
|
||||
Prefixes: Prefixes,
|
||||
Suffixes: Suffixes,
|
||||
Words: Words,
|
||||
}
|
||||
}
|
||||
|
||||
func (wf *WordFilter) F(prefix, suffix string) int {
|
||||
prefix_base, ok := wf.Prefixes, true
|
||||
for i := range prefix {
|
||||
prefix_base, ok = prefix_base.Map[prefix[i]]
|
||||
if !ok {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
suffix_base := wf.Suffixes
|
||||
for i := len(suffix) - 1; i >= 0; i-- {
|
||||
suffix_base, ok = suffix_base.Map[suffix[i]]
|
||||
if !ok {
|
||||
return -1
|
||||
}
|
||||
}
|
||||
prefix_found := map[string]bool{}
|
||||
for _, found := range prefix_base.CombineAllSubStrings(prefix, false) {
|
||||
prefix_found[found] = true
|
||||
}
|
||||
|
||||
max := -1
|
||||
for _, found := range suffix_base.CombineAllSubStrings(suffix, true) {
|
||||
if _, ok := prefix_found[found]; ok {
|
||||
idx := wf.Words[found]
|
||||
if idx > max {
|
||||
max = idx
|
||||
}
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
/**
|
||||
* Your WordFilter object will be instantiated and called as such:
|
||||
* obj := Constructor(words);
|
||||
* param_1 := obj.F(prefix,suffix);
|
||||
*/
|
|
@ -0,0 +1,31 @@
|
|||
impl Solution {
|
||||
pub fn suggested_products(products: Vec<String>, search_word: String) -> Vec<Vec<String>> {
|
||||
// Products list mapped to maximum common prefix length with search_word
|
||||
let max_prefix_matches = products.iter()
|
||||
.map(|product| product.bytes()
|
||||
.zip(search_word.bytes())
|
||||
.take_while(|&(chr1, chr2)| chr1 == chr2)
|
||||
.count()
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
search_word.bytes()
|
||||
.enumerate()
|
||||
.map(|(chr_idx, chr)| {
|
||||
// Get all options that match at least chr_idx prefix length
|
||||
let mut options = max_prefix_matches.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(product_idx, &max_prefix_match)| {
|
||||
if max_prefix_match > chr_idx {
|
||||
Some(&products[product_idx])
|
||||
} else { None }
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
options.sort(); // TODO : Could optimise since we are only taking 3 smallest elements
|
||||
options.into_iter()
|
||||
.take(3)
|
||||
.map(|s| s.clone())
|
||||
.collect()
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue