国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[Leetcode] Word Search I&II 二維字符矩陣查找單詞

LuDongWei / 3447人閱讀

摘要:復(fù)雜度時(shí)間空間為長度,為大小空間復(fù)雜度是是因?yàn)槲矣么嫘畔ⅲ粍?dòng)態(tài)地存當(dāng)前的路徑如果用來存信息的話空間復(fù)雜度就是時(shí)間復(fù)雜度對每個(gè)點(diǎn)都要作為起始點(diǎn),對于每個(gè)起始點(diǎn),拓展一次有四個(gè)可能性四個(gè)鄰居,要拓展次長度為。思路暴力搜索帶走。

Word Search I

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same >letter cell may not be used more than once.

For example, Given board =

[
 ["ABCE"],
 ["SFCS"],
 ["ADEE"]
]

word = "ABCCED", -> returns true, word = "SEE", -> returns true, word = "ABCB", -> returns false.

DFS 復(fù)雜度

O(MN*4^K ) 時(shí)間 O(K) 空間
K為word長度, M*N為board大小
空間復(fù)雜度是K是因?yàn)槲矣肏ashSet存visited信息,只動(dòng)態(tài)地存當(dāng)前dfs的路徑;如果用boolean[][]來存visited信息的話空間復(fù)雜度就是O(MN)
時(shí)間復(fù)雜度:對每個(gè)點(diǎn)都要作為起始點(diǎn)dfs,對于每個(gè)起始點(diǎn),拓展一次有四個(gè)可能性(四個(gè)鄰居),要拓展k次(word長度為k)。

思路

暴力搜索帶走。

注意

visited可以有多種實(shí)現(xiàn)方法:

boolean[ ] [ ] visited

HashSet visited,用個(gè)小trick把二維坐標(biāo)轉(zhuǎn)化為一維

二維轉(zhuǎn)一維:(x,y) -> index : index = x * col + y

一維轉(zhuǎn)二維:index -> (x,y) : x = index / col; y = index % col;

直接修改board數(shù)組,將訪問過的格子改成特定字符比如 "#" 或者 "$"等

代碼
public class Solution {
    public boolean exist(char[][] board, String word) {
        HashSet visited = new HashSet();
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                if (hasPath(0, i, j, word, board, visited))
                    return true;
            }
        }
        return false;
    }
    //找(x,y)是不是這個(gè)詞
    public boolean hasPath(int pos, int x, int y, String word, char[][] board, HashSet visited) {
        if (pos == word.length() - 1) {
            if (board[x][y] == word.charAt(pos))
                return true;
            else
                return false;
        }
        else {
            char target = word.charAt(pos);
            if (target == board[x][y]) {
                visited.add(x * board[0].length + y);
                int[] dirx = {0, 0, 1, -1};
                int[] diry = {1, -1, 0, 0};
                for (int i = 0; i < 4; i++) {
                    int newx = x + dirx[i];
                    int newy = y + diry[i];
                    if (isValid(newx, newy, board) && !visited.contains(newx * board[0].length + newy)) {
                            if (hasPath(pos + 1, newx, newy, word, board, visited))
                                return true;
                    }
                }
                visited.remove(x * board[0].length + y);
                return false;
            }
            else {
                return false;
            }
        }
    }
    public boolean isValid(int x, int y, char[][] board) {
        if (x >= 0 && x <= board.length - 1 && y >= 0 && y <= board[0].length - 1)
            return true;
        else
            return false;
    }
}
Word Search II

Given a 2D board and a list of words from the dictionary, find all words in the board.

Each word must be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once in a word.

For example, Given words = ["oath","pea","eat","rain"] and board =

[
  ["o","a","a","n"],
  ["e","t","a","e"],
  ["i","h","k","r"],
  ["i","f","l","v"]
] 

Return ["eat","oath"].

Trie + DFS 復(fù)雜度

O(MN*4^K ) 時(shí)間 O(MN) 空間
K為word最大長度, M*N為board大小
空間復(fù)雜度:用boolean[][]來存visited信息
時(shí)間復(fù)雜度:對每個(gè)點(diǎn)都要作為起始點(diǎn)dfs,對于每個(gè)起始點(diǎn),拓展一次有四個(gè)可能性(四個(gè)鄰居),要拓展k次(word最大長度為k)。

思路

要用trie,拿trie來dfs
先建trie,然后在board里搜所有trie里的word

遞歸函數(shù)接口:

public void hasPath(int x, int y, 
                    char[][] board, 
                    boolean[][] visited, 
                    Trie trie, 
                    StringBuilder sb, 
                    List result)

滿足的property:在進(jìn)入hasPath的一剎那,1.(x,y)還沒有訪問;2.(x,y)是valid的而且還沒有被訪問過;3.此時(shí)的dfs快照是sb和visited

注意

盡管visited可以有多種實(shí)現(xiàn)方法,這一題用1,3都可以,用2就會(huì)超時(shí):

boolean[ ] [ ] visited

HashSet visited,用個(gè)小trick把二維坐標(biāo)轉(zhuǎn)化為一維

二維轉(zhuǎn)一維:(x,y) -> index : index = x * col + y

一維轉(zhuǎn)二維:index -> (x,y) : x = index / col; y = index % col;

直接修改board數(shù)組,將訪問過的格子改成特定字符比如 "#" 或者 "$"等

代碼

Trie Utility:

class Trie {
    private static final int R = 26;
    TrieNode root = new TrieNode();
    
    private static class TrieNode {
        private boolean isWord = false;
        private TrieNode[] children = new TrieNode[R];
    }
    
    public void insert(String word) {
        TrieNode cur = root;
        for (int i = 0; i < word.length(); i++) {
            if (cur.children[word.charAt(i) - "a"] == null) {
                cur.children[word.charAt(i) - "a"] = new TrieNode();
            }
            cur = cur.children[word.charAt(i) - "a"];
            if (i == word.length() - 1)
                cur.isWord = true;
        }
    }
    
    public boolean search(String word) {
        TrieNode cur = root;
        for (int i = 0; i < word.length(); i++) {
            if (cur.children[word.charAt(i) - "a"] == null)
                return false;
            else {
                if (i == word.length() - 1)
                    return cur.children[word.charAt(i) - "a"].isWord;
                else {
                    cur = cur.children[word.charAt(i) - "a"];
                }
            }
        }
        return false;
    }
    
    public boolean startsWith(String word) {
        TrieNode cur = root;
        for (int i = 0; i < word.length(); i++) {
            if (cur.children[word.charAt(i) - "a"] == null) {
                return false;
            }    
            cur = cur.children[word.charAt(i) - "a"];
        }
        return true;
    }
    
}

主程序

public class Solution {
    public List findWords(char[][] board, String[] words) {
        List result = new ArrayList();
        Trie trie = new Trie();
        boolean[][] visited = new boolean[board.length][board[0].length];
        for (String str : words)
            trie.insert(str);
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                //帶著當(dāng)前的string去explore(i,j)這個(gè)點(diǎn)
                hasPath(i, j, board, visited, trie, new StringBuilder(), result);
            }
        }
        return result;
    }
    //x,y是合法的,sb里存得也是合法的,(x,y)還沒有explore
    public void hasPath(int x, int y, char[][] board, boolean[][] visited, Trie trie, StringBuilder sb, List result) {
        //explore (x,y)
        sb.append(board[x][y]);
        visited[x][y] = true;
        //does (x,y) make sense? do this only when it does
        if (trie.startsWith(sb.toString())) {
            if (trie.search(sb.toString())) {
                if (!result.contains(sb.toString()))
                    result.add(sb.toString());
            }
            int[] dirx = {0,0,1,-1};
            int[] diry = {1,-1,0,0};
            for (int i = 0; i < 4; i++) {
                int newx = x + dirx[i];
                int newy = y + diry[i];
                if (isValid(newx, newy, board) && !visited[newx][newy]) {
                    hasPath(newx, newy, board, visited, trie, sb, result);
                }
            }
        }
        //finished exploring (x,y),let"s go back explore another one
        visited[x][y] = false;
        sb.deleteCharAt(sb.length() - 1);
    }
    public boolean isValid(int x, int y, char[][] board) {
        if (x >= 0 && x <= board.length - 1 && y >= 0 && y <= board[0].length - 1)
            return true;
        else
            return false;
    }
}

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64814.html

相關(guān)文章

  • [Leetcode] Word Search 單詞搜索

    摘要:我們可以先用待查單詞建立一個(gè)字典樹,這樣我們在從矩陣中某個(gè)點(diǎn)開始深度優(yōu)先搜索時(shí),可以直接用字典樹判斷當(dāng)前組成的字符串是否是某個(gè)單詞的前綴。字典樹同樣也提供接口,所以同樣可以用于判斷是否已經(jīng)搜索到這個(gè)詞了。 Word Search I 更新的思路與解法請?jiān)L問:https://yanjia.me/zh/2018/11/... Given a 2D board and a word, f...

    objc94 評論0 收藏0
  • 前端 | 每天一個(gè) LeetCode

    摘要:在線網(wǎng)站地址我的微信公眾號(hào)完整題目列表從年月日起,每天更新一題,順序從易到難,目前已更新個(gè)題。這是項(xiàng)目地址歡迎一起交流學(xué)習(xí)。 這篇文章記錄我練習(xí)的 LeetCode 題目,語言 JavaScript。 在線網(wǎng)站:https://cattle.w3fun.com GitHub 地址:https://github.com/swpuLeo/ca...我的微信公眾號(hào): showImg(htt...

    張漢慶 評論0 收藏0
  • 6-9月技術(shù)文章匯總

    摘要:分布式的管理和當(dāng)我在談?wù)摷軜?gòu)時(shí)我在談啥狀態(tài)碼詳解無狀態(tài)協(xié)議和請求支持哪些方法分層協(xié)議棧有哪些數(shù)據(jù)結(jié)構(gòu)運(yùn)用場景說說你常用的命令為什么要有包裝類面向?qū)ο蟮奶卣魇巧妒巧队惺裁春锰幭到y(tǒng)設(shè)計(jì)工程在線診斷系統(tǒng)設(shè)計(jì)與實(shí)現(xiàn)索引背后的數(shù)據(jù)結(jié)構(gòu)及算法原理軟技能 HTTP 【HTTP】分布式session的管理 【HTTP】Cookie和Session 【HTTP】當(dāng)我在談?wù)揜estFul架構(gòu)時(shí)我在談啥?...

    miya 評論0 收藏0
  • Word Break I, II &amp; Concatenated Words

    摘要:所以現(xiàn)在里面應(yīng)該存可以使長度為所有可能的里的最后一個(gè)。有兩種寫法,一個(gè)就是直接寫成數(shù)組的形式,不能形成的。結(jié)束之后,第二步就是通過里面保存的,一步一步回溯找到所有結(jié)果。直接的會(huì)超時(shí),考慮記憶化搜索。所以事先對排序。 Word Break 鏈接:https://leetcode.com/problems... 這種找一個(gè)詞由多個(gè)詞組成的題,是拿dp或者dfs來解,dp本質(zhì)上其實(shí)也是dfs...

    sunsmell 評論0 收藏0
  • LeetCode 精選TOP面試題【51 ~ 100】

    摘要:有效三角形的個(gè)數(shù)雙指針最暴力的方法應(yīng)該是三重循環(huán)枚舉三個(gè)數(shù)字。總結(jié)本題和三數(shù)之和很像,都是三個(gè)數(shù)加和為某一個(gè)值。所以我們可以使用歸并排序來解決這個(gè)問題。注意因?yàn)闅w并排序需要遞歸,所以空間復(fù)雜度為 ...

    Clect 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<