some more problems

This commit is contained in:
Gleb Koval 2022-06-19 22:57:33 +01:00
parent 3cc60d0431
commit 4a14268528
Signed by: cyclane
GPG Key ID: 15E168A8B332382C
7 changed files with 328 additions and 0 deletions

View File

@ -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
}

View File

@ -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")));
}

View File

@ -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

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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);
*/

View File

@ -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()
}
}