vozerbanpho
Junior Member
Tại sao cái này là không phải valid binary search tree nhỉ, mình vẫn chưa hiểu.
45 nằm trong left subtree của 30 nên nó sai.Tại sao cái này là không phải valid binary search tree nhỉ, mình vẫn chưa hiểu.
View attachment 2509754
Thanks chủ tịch.45 nằm trong left subtree của 30 nên nó sai.
impl Solution {
pub fn max_score_words(words: Vec<String>, letters: Vec<char>, letter_scores: Vec<i32>) -> i32 {
let n = words.len();
let mut word_letter_freqs: Vec<Vec<i32>> = vec![vec![0i32; 26]; n];
for (i, word) in words.into_iter().enumerate() {
for &bc in word.as_bytes().into_iter() {
word_letter_freqs[i][(bc - b'a') as usize] += 1;
}
}
let mut letter_freqs = vec![0i32; 26];
for c in letters.into_iter() {
letter_freqs[((c as u8) - b'a') as usize] += 1;
}
Self::backtrack(
&word_letter_freqs,
&mut letter_freqs,
&letter_scores,
0
)
}
pub fn backtrack(
rem_word_letter_freqs: &[Vec<i32>],
letter_freqs: &mut Vec<i32>,
letter_scores: &Vec<i32>,
score: i32
) -> i32
{
let l = rem_word_letter_freqs.len();
if l == 0 {
return score;
}
let mut max_score = score;
for i in 0..l {
let word_letter_freqs = &rem_word_letter_freqs[i];
let mut should_call = true;
let mut prop_score = score;
for j in 0..26 {
letter_freqs[j] -= word_letter_freqs[j];
prop_score += letter_scores[j] * word_letter_freqs[j];
should_call = should_call && (letter_freqs[j] >= 0);
}
if should_call {
let new_score =
Self::backtrack(
&rem_word_letter_freqs[(i + 1)..],
letter_freqs,
letter_scores,
prop_score
);
max_score = max_score.max(new_score);
}
for j in 0..26 {
letter_freqs[j] += word_letter_freqs[j];
}
let new_score =
Self::backtrack(
&rem_word_letter_freqs[(i + 1)..],
letter_freqs,
letter_scores,
score
);
max_score = max_score.max(new_score);
}
max_score
}
}
impl Solution {
pub fn max_score_words(words: Vec<String>, letters: Vec<char>, letter_scores: Vec<i32>) -> i32 {
let n = words.len();
let mut word_letter_freqs: Vec<Vec<i32>> = vec![vec![0i32; 26]; n];
for (i, word) in words.into_iter().enumerate() {
for &bc in word.as_bytes().into_iter() {
word_letter_freqs[i][(bc - b'a') as usize] += 1;
}
}
let mut letter_freqs = vec![0i32; 26];
for c in letters.into_iter() {
letter_freqs[((c as u8) - b'a') as usize] += 1;
}
Self::backtrack(
&word_letter_freqs,
&mut letter_freqs,
&letter_scores,
0
)
}
pub fn backtrack(
rem_word_letter_freqs: &[Vec<i32>],
letter_freqs: &mut Vec<i32>,
letter_scores: &Vec<i32>,
score: i32
) -> i32
{
let l = rem_word_letter_freqs.len();
if l == 0 {
return score;
}
let mut max_score = score;
for i in 0..l {
let word_letter_freqs = &rem_word_letter_freqs[i];
let mut should_call = true;
let mut prop_score = score;
for j in 0..26 {
letter_freqs[j] -= word_letter_freqs[j];
prop_score += letter_scores[j] * word_letter_freqs[j];
should_call = should_call && (letter_freqs[j] >= 0);
}
if should_call {
let new_score =
Self::backtrack(
&rem_word_letter_freqs[(i + 1)..],
letter_freqs,
letter_scores,
prop_score
);
max_score = max_score.max(new_score);
}
for j in 0..26 {
letter_freqs[j] += word_letter_freqs[j];
}
}
max_score
}
}
impl Solution {
pub fn max_score_words(words: Vec<String>, letters: Vec<char>, letter_scores: Vec<i32>) -> i32 {
let n = words.len();
let mut letter_freqs = vec![0i32; 26];
for c in letters.into_iter() {
letter_freqs[((c as u8) - b'a') as usize] += 1;
}
Self::backtrack(&words, &mut letter_freqs, &letter_scores, 0)
}
pub fn backtrack(
rem_words: &[String], letter_freqs: &mut Vec<i32>, letter_scores: &Vec<i32>, score: i32
) -> i32
{
let l = rem_words.len();
if l == 0 {
return score;
}
let mut max_score = score;
for i in 0..l {
let word = &rem_words[i];
let mut should_call = true;
let mut prop_score = score;
for &bc in word.as_bytes().iter() {
let index = (bc - b'a') as usize;
letter_freqs[index] -= 1;
prop_score += letter_scores[index];
should_call = should_call && (letter_freqs[index] >= 0);
}
if should_call {
let new_score =
Self::backtrack(&rem_words[(i + 1)..], letter_freqs, letter_scores, prop_score);
max_score = max_score.max(new_score);
}
for &bc in word.as_bytes().iter() {
let index = (bc - b'a') as usize;
letter_freqs[index] += 1;
}
}
max_score
}
}
Viết dài quá sẽ khó debug, viết 1 line thì bị Vozers chửimột con gà ngồi debug![]()
Code:impl Solution { pub fn max_score_words(words: Vec<String>, letters: Vec<char>, letter_scores: Vec<i32>) -> i32 { let n = words.len(); let mut word_letter_freqs: Vec<Vec<i32>> = vec![vec![0i32; 26]; n]; for (i, word) in words.into_iter().enumerate() { for &bc in word.as_bytes().into_iter() { word_letter_freqs[i][(bc - b'a') as usize] += 1; } } let mut letter_freqs = vec![0i32; 26]; for c in letters.into_iter() { letter_freqs[((c as u8) - b'a') as usize] += 1; } Self::backtrack( &word_letter_freqs, &mut letter_freqs, &letter_scores, 0 ) } pub fn backtrack( rem_word_letter_freqs: &[Vec<i32>], letter_freqs: &mut Vec<i32>, letter_scores: &Vec<i32>, score: i32 ) -> i32 { let l = rem_word_letter_freqs.len(); if l == 0 { return score; } let mut max_score = score; for i in 0..l { let word_letter_freqs = &rem_word_letter_freqs[i]; let mut should_call = true; let mut prop_score = score; for j in 0..26 { letter_freqs[j] -= word_letter_freqs[j]; prop_score += letter_scores[j] * word_letter_freqs[j]; should_call = should_call && (letter_freqs[j] >= 0); } if should_call { let new_score = Self::backtrack( &rem_word_letter_freqs[(i + 1)..], letter_freqs, letter_scores, prop_score ); max_score = max_score.max(new_score); } for j in 0..26 { letter_freqs[j] += word_letter_freqs[j]; } let new_score = Self::backtrack( &rem_word_letter_freqs[(i + 1)..], letter_freqs, letter_scores, score ); max_score = max_score.max(new_score); } max_score } }
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
wordSet = set(wordDict)
words = []
def dp(index, currentWord):
if index == len(s):
words.append(currentWord)
for i in range(index, len(s)):
word = s[index: i + 1]
if word in wordSet:
nextWord = word if currentWord == "" else currentWord + " " + word
dp(i + 1, nextWord)
dp(0, "")
return words
T nghĩ bài này dễ là do cái S ngắn quá (<=20). Nên k cần setup gì đặc biệt vẫn pass. Cho dài tí là phải setup cái trie để search thì mới pass đc, lúc đó sẽ khó hơn chútBài này medium thôi còn ko tới medium hard nữa ấy chứ
Python:class Solution: def wordBreak(self, s: str, wordDict: List[str]) -> List[str]: wordSet = set(wordDict) words = [] def dp(index, currentWord): if index == len(s): words.append(currentWord) for i in range(index, len(s)): word = s[index: i + 1] if word in wordSet: nextWord = word if currentWord == "" else currentWord + " " + word dp(i + 1, nextWord) dp(0, "") return words
Đúng rồi xài trie optimize tí như bài word break cũng được. Mình lúc đầu làm cũng bất ngờ là xài set beat cả đống luôn.T nghĩ bài này dễ là do cái S ngắn quá (<=20). Nên k cần setup gì đặc biệt vẫn pass. Cho dài tí là phải setup cái trie để search thì mới pass đc, lúc đó sẽ khó hơn chút
fun wordBreak(s: String, wordDict: List<String>): List<String> {
val dp = Array(s.length) { mutableListOf<String>() }
for (i in s.indices) {
val sub = s.substring(0, i + 1)
for (word in wordDict) {
if (sub == word) {
dp[i].add(word)
} else if (sub.endsWith(word)) {
for (sentence in dp[i - word.length]) {
dp[i].add("$sentence $word")
}
}
}
}
return dp.last()
}
class Solution {
func wordBreak(_ s: String, _ wordDict: [String]) -> [String] {
// Build dict...
var dict:[[Character]:Bool] = [:]
for str in wordDict {
let chars = [Character](str)
if chars.count > 1 {
for num in 1...chars.count-1 {
let subChars = Array(chars[0..<num])
dict[subChars] = false
}
}
}
for str in wordDict {
let chars = [Character](str)
dict[chars] = true
}
// Check s
var res:[[Character]] = []
func dfs(c: [Character], i: Int) {
var l = 1
while (i+l <= c.count) {
let subC = Array(c[i..<i+l])
if let isWord = dict[subC] {
if isWord {
if (i+l) == c.count {
res.append(c)
break
}
var newChars = c
newChars.insert(" ", at: i+l)
dfs(c: newChars, i: i+l+1)
}
l += 1
} else {
break
}
}
}
dfs(c: [Character](s), i: 0)
return res.map { String($0) }
}
}
Chắc tính từ thời đi học nữa nên mới chênh với kinh nghiệm software 3 nămLượn lờ thấy mấy job big tech yêu cầu kinh nghiệm algorithm 8 nămcó Vozers nào luyện algo 8 năm chưa nhỉ
![]()
via theNEXTvoz for iPhone
hashmap O(1) rồi setup trie làm gì nữa bácT nghĩ bài này dễ là do cái S ngắn quá (<=20). Nên k cần setup gì đặc biệt vẫn pass. Cho dài tí là phải setup cái trie để search thì mới pass đc, lúc đó sẽ khó hơn chút
Trie để early termination bác.hashmap O(1) rồi setup trie làm gì nữa bác
class Solution(object):
def wordBreak(self, s, wordDict):
"""
:type s: str
:type wordDict: List[str]
:rtype: List[str]
"""
wordHash = {}
for word in wordDict:
wordHash[word] = True
def innerWordBreak(s, start_idx, current_idx):
result = []
cur = s[start_idx:current_idx]
if cur in wordHash:
if current_idx == len(s):
result.append(cur)
else:
result1 = innerWordBreak(s, current_idx, current_idx + 1)
for tmp in result1:
result.append(cur + " " + tmp)
if current_idx == len(s):
return result
else:
result2 = innerWordBreak(s, start_idx, current_idx + 1)
return result + result2
return innerWordBreak(s, 0, 1)
3 năm lead, 5 năm dev kìa thímChắc tính từ thời đi học nữa nên mới chênh với kinh nghiệm software 3 năm![]()
rồi, đủ combo áo + lót ly + móc khoá + stickerAnh em có ai tích đủ coin đổi cái áo LeetCode chưa nhỉ
Mình đang tính duy trì 2 tháng nữa là đủ coin![]()
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> List[str]:
result, n = [], len(s)
wordSet = set(wordDict)
def backtracking(i, current):
if i == n:
result.append(" ".join(current))
for j in range(i, n):
if s[i:j+1] in wordSet:
current.append(s[i:j+1])
backtracking(j + 1, current)
current.pop()
backtracking(0, [])
return result
Trie để early termination bác.
Ví dụ như bác dùng set thì chỉ chứa các từ có 3 kí tự chả hạn vd "abc", "aed". Mà bác đang backtrack ở 2 kí tự vd "df" thì bác phải đi tới kí tự thứ 3 để chắc chắn là trong set ko tồn tại cái chuỗi "dfg" cần tìm.
Nhưng mà nếu dùng trie thì ngay từ chữ "d" đầu tiên thì bác đã biết là ko có từ nào bắt đầu bằng "d" trong trie cả và break backtracking luôn.
via theNEXTvoz for iPhone