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