摘要:題目鏈接暴力遍歷,一個(gè)一個(gè)檢查看符不符合要求。首先這種需要求出所有結(jié)果的題,一般都是用的。因?yàn)轭}目已經(jīng)說了的長度范圍是到,最多考慮五個(gè)單詞即可。首先是肯定都需要的,兩種或者。如果題目要求返回所有以特定的開頭的單詞,那么可以用。
Valid Word Square
題目鏈接:https://leetcode.com/problems...
暴力遍歷,一個(gè)一個(gè)檢查看符不符合要求。
public boolean validWordSquare(ListWord Squareswords) { /* words[i][j] == words[j][i] * j >= len(words) or i >= len(words[j]) return false */ for(int i = 0; i < words.size(); i++) { String word = words.get(i); for(int j = 0; j < word.length(); j++) { if(j >= words.size() || i >= words.get(j).length()) return false; if(word.charAt(j) != words.get(j).charAt(i)) return false; } } return true; }
題目鏈接:https://leetcode.com/problems...
這道題如果用上一題的方法,一個(gè)一個(gè)試的話,時(shí)間復(fù)雜度太高。所以要另想辦法。
首先這種需要求出所有結(jié)果的題,一般都是用dfs(backtracking)的。然后這道題的思路是單詞一個(gè)一個(gè)確定。因?yàn)轭}目已經(jīng)說了word的長度范圍是1到5,最多考慮五個(gè)單詞即可。
第一個(gè)單詞:""為前綴,在words數(shù)組里隨便取一個(gè)word1,確定長度
第二個(gè)單詞:在剩下的words里取出一個(gè)以word1[1]為前綴的word2
第三個(gè)單詞:在剩下的里取出一個(gè)以word1[2]+word2[2]為前綴的word3
第四個(gè)單詞:在剩下的里取出一個(gè)以word1[3]+word2[3]+word3[3]為前綴的word4
第五個(gè)單詞:在剩下的里取出一個(gè)以word1[4]+word2[4]+word3[4]+word4[4]為前綴的word5
所以這題需要快速的找到前綴,那么可以想到用hashmap或者trie tree。題目說了單詞沒有duplication,省去了查重的過程。
遍歷words,把其中的一個(gè)單詞當(dāng)作1st word
找到第二個(gè)單詞,加到square里面,接著找第三個(gè)單詞......這是個(gè)backtracking的過程,如果prefix不在trie tree里面直接return
找第二個(gè),第三個(gè),。。。單詞的過程用的是bfs,已經(jīng)知道prefix之后,根據(jù)prefix找到trie tree里面對應(yīng)的node,從改node開始bfs走剩下的長度,找到所有可能的node,檢查這些node是否是單詞的末尾,是的話就放入list里面,給上面dfs的method來用
public class Solution { public List> wordSquares(String[] words) { // hashmap or trie tree TrieNode root = buildTrieTree(words); // traverse all word int words, for the 1st word for(String word : words) { // len(word) == 1, itself is square if(word.length() == 1) { List
cur = new ArrayList(); cur.add(word); result.add(cur); continue; } List square = new ArrayList(); square.add(word); dfs(root, square); } return result; } List > result = new ArrayList(); /* from the idx position in words * 1st word: a = words[i] * 2nd word: b prefix = a.charAt(1) * 3rd word: c prefix = a.charAt(2) + b.charAt(2) * 4th word: d prefix = a.charAt(3) + b.charAt(3) + c.charAt(3) * 5th word: e prefix = a.charAt(4) + b.charAt(4) + c.charAt(4) + d.charAt(4) */ private void dfs(TrieNode root, List
square) { int len = square.get(0).length(); int prefix_length = square.size(); if(len == prefix_length) { result.add(new ArrayList(square)); return; } String prefix = ""; // find supposed prefix for(int i = 0; i < prefix_length; i++) prefix += square.get(i).charAt(prefix_length); // find word with that prefix in trie tree TrieNode node = root; for(int i = 0; i < prefix.length(); i++) { if(node.children[getIndex(prefix.charAt(i))] == null) return; node = node.children[getIndex(prefix.charAt(i))]; } List next = bfs(node, len - prefix_length); if(next.size() == 0) return; for(String s : next) { square.add(s); dfs(root, square); square.remove(square.size() - 1); } } // find all possible words with certain prefix private List bfs(TrieNode node, int left) { List possible = new ArrayList(); Queue q = new LinkedList(); q.offer(node); while(left-- > 0) { if(q.isEmpty()) break; for(int j = q.size(); j > 0; j--) { TrieNode cur = q.poll(); for(int i = 0; i < 26; i++) { if(cur.children[i] != null) q.offer(cur.children[i]); } } } for(TrieNode cur : q) { if(cur.word != null) possible.add(cur.word); } return possible; } private int getIndex(char c) { return c - "a"; } class TrieNode { TrieNode[] children = new TrieNode[26]; String word = ""; } private TrieNode buildTrieTree(String[] words) { TrieNode root = new TrieNode(); for(String word : words) { TrieNode cur = root; for(int i = 0; i < word.length(); i++) { if(cur.children[getIndex(word.charAt(i))] == null) { cur.children[getIndex(word.charAt(i))] = new TrieNode(); } cur = cur.children[getIndex(word.charAt(i))]; } cur.word = word; } return root; } }
看了discussion的方法,直接在構(gòu)造trie的時(shí)候,在node里面加上以它為prefix所有可能的word,這樣多加了一個(gè)List
public class Solution { public ListTrie Tree的構(gòu)造方法> wordSquares(String[] words) { // hashmap or trie tree TrieNode root = buildTrieTree(words); // traverse all word int words, for the 1st word for(String word : words) { // len(word) == 1, itself is square if(word.length() == 1) { List
cur = new ArrayList(); cur.add(word); result.add(cur); continue; } List square = new ArrayList(); square.add(word); dfs(root, square); } return result; } List > result = new ArrayList(); private void dfs(TrieNode root, List
square) { int len = square.get(0).length(); if(len == square.size()) { result.add(new ArrayList(square)); return; } // find all words with prefix List next = findWords(root, square); for(String s : next) { square.add(s); dfs(root, square); square.remove(square.size() - 1); } } private List findWords(TrieNode node, List square) { String prefix = ""; int prefix_length = square.size(); // find supposed prefix for(int i = 0; i < prefix_length; i++) prefix += square.get(i).charAt(prefix_length); // find word with that prefix in trie tree for(int i = 0; i < prefix.length(); i++) { if(node.children[getIndex(prefix.charAt(i))] == null) return new ArrayList(); node = node.children[getIndex(prefix.charAt(i))]; } return node.wordsWithPrefix; } private int getIndex(char c) { return c - "a"; } class TrieNode { TrieNode[] children = new TrieNode[26]; List wordsWithPrefix = new ArrayList(); } private TrieNode buildTrieTree(String[] words) { TrieNode root = new TrieNode(); for(String word : words) { TrieNode cur = root; for(int i = 0; i < word.length(); i++) { if(cur.children[getIndex(word.charAt(i))] == null) { cur.children[getIndex(word.charAt(i))] = new TrieNode(); } cur = cur.children[getIndex(word.charAt(i))]; cur.wordsWithPrefix.add(word); } } return root; } }
cc150上面給了Trie和TrieNode的構(gòu)造方法。感覺lc里面主要是高清TrieNode的fields,以及對應(yīng)的build一個(gè)Trie的方法。lc上一共7道trie的題,出現(xiàn)過的TrieNode的fields不同的選擇好像就3種。
首先children是肯定都需要的,兩種:array(TrieNode[])或者HashMap(Map
然后還用到的fields有:isWord(boolean:結(jié)尾,判斷是否形成一個(gè)單詞), word(String:結(jié)尾,形成的單詞)以及startsWith(List
如果題目只要求判斷單詞在不在字典里,isWord就夠了。
如果題目要求返回String,那么一般用word。
如果題目要求返回所有以特定的prefix開頭的單詞,那么可以用startsWith。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/66559.html
Problem Given a set of words (without duplicates), find all word squares you can build from them. A sequence of words forms a valid word square if the kth row and column read the exact same string, wh...
摘要:我們要滿足都可以作為開頭的部分。按照代碼的邏輯,走一遍填寫好每一步被更新的樣子。開始結(jié)束同一層從左向右走的時(shí)候會(huì)不斷增長,直到最后形成以個(gè)單詞相應(yīng)位置長度加一,更新重新進(jìn)行下一次的搜索。 題目描述請見leetcode 425 w a l l a r e a l e a d l a d y 在給定的詞典里,找到一些單詞,組成一個(gè)square, 第i行和第i列一樣。(0,0) 這個(gè)點(diǎn)找到滿...
摘要:中的注釋是以開頭,并且一直延申到該文本結(jié)束為止。例如的長度為使用過大的索引會(huì)產(chǎn)生一個(gè)錯(cuò)誤但是在切片中,越界索引會(huì)被自動(dòng)處理中的字符串不能被修改,它們是的。其中最常用的列表,可以通過方括號括起逗號分隔的一組值得到。 在下面的例子中通過提示符(>>>與...)的出現(xiàn)與否來區(qū)分輸入和輸出:如果你想復(fù)現(xiàn)這些例子,當(dāng)提示符出現(xiàn)后,你必須在提示符后鍵入例子中的每一個(gè)詞;不以提示符開頭的那些行是解釋...
摘要:在線嘗試的進(jìn)程管理工具。項(xiàng)目包含了代碼實(shí)現(xiàn)運(yùn)行過程動(dòng)畫以及相關(guān)論文為系統(tǒng)提供人臉識別解鎖電腦的工具。在線閱讀教科書計(jì)算機(jī)體系結(jié)構(gòu)基礎(chǔ)第三版。 .markdown-body{word-break:break-word;line-height:1.75;font-weight:400;font-size:15px;overflow-x:hidden;color:#333}.markdown-b...
摘要:從到有兩種新的方式來聲明變量用于聲明塊級作用于變量用于聲明常量,其值不能被改變。更多信息箭頭函數(shù)處理多個(gè)返回值一些函數(shù)或方法能通過數(shù)組或?qū)ο蠓祷囟鄠€(gè)值。在中,總是需要?jiǎng)?chuàng)建中間變量來訪問返回值。內(nèi)置了模塊語法,但并沒有得到引擎良好支持。 1. 嘗試ES6 這里有三種簡單地方式用于ES6編程: Web瀏覽器:使用Babel REPL,可以將ES6編譯成ES5的平臺(tái),并且并不需要安裝。 命...
閱讀 1223·2021-11-25 09:43
閱讀 1337·2021-09-26 09:55
閱讀 2330·2021-09-10 11:20
閱讀 3365·2019-08-30 15:55
閱讀 1441·2019-08-29 13:58
閱讀 1164·2019-08-29 12:36
閱讀 2337·2019-08-29 11:18
閱讀 3407·2019-08-26 11:47