zoukankan      html  css  js  c++  java
  • Java for LeetCode 212 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"].

    解题思路:

    本题承接自Java for LeetCode 079 Word Search 但是用dfs会TLE,真正的做法是将word放进Trie里面,然后遍历trie里的每个点,看是否能匹配到trie里的元素,JAVA实现如下:

    public class Solution {
    	public List<String> findWords(char[][] board, String[] words) {  
    		HashSet<String> list=new HashSet();
    		Trie trie = new Trie();  
            for (String word : words)
                trie.insert(word);   
            boolean[][] visited=new boolean[board.length][board[0].length];
            for (int i = 0; i < board.length; i++) 
                for (int j = 0; j < board[0].length; j++)
                    dfs(list,board, visited, "", i, j, trie);   
            return new ArrayList(list);  
        }  
          
        public void dfs(Set<String> list,char[][] board, boolean[][] visited, String str, int x, int y, Trie trie) {  
            if (x < 0 || x >= board.length || y < 0 || y >= board[0].length)
            	return;  
            if (visited[x][y]) 
            	return;  
            str += board[x][y];  
            if (!trie.startsWith(str)) 
            	return;  
            if (trie.search(str)) 
                list.add(str);
            visited[x][y] = true;  
            dfs(list,board, visited, str, x - 1, y, trie);  
            dfs(list,board, visited, str, x + 1, y, trie);  
            dfs(list,board, visited, str, x, y - 1, trie);  
            dfs(list,board, visited, str, x, y + 1, trie);  
            visited[x][y] = false;  
        }  
    }
    class TrieNode {
    	// Initialize your data structure here.
    	int num;// 有多少单词通过这个节点,即节点字符出现的次数
    	TrieNode[] son;// 所有的儿子节点
    	boolean isEnd;// 是不是最后一个节点
    	char val;// 节点的值
    
    	TrieNode() {
    		this.num = 1;
    		this.son = new TrieNode[26];
    		this.isEnd = false;
    	}
    }
    
    class Trie {
    	protected TrieNode root;
    
    	public Trie() {
    		root = new TrieNode();
    	}
    
    	public void insert(String word) {
    		if (word == null || word.length() == 0)
    			return;
    		TrieNode node = this.root;
    		char[] letters = word.toCharArray();
    		for (int i = 0; i < word.length(); i++) {
    			int pos = letters[i] - 'a';
    			if (node.son[pos] == null) {
    				node.son[pos] = new TrieNode();
    				node.son[pos].val = letters[i];
    			} else {
    				node.son[pos].num++;
    			}
    			node = node.son[pos];
    		}
    		node.isEnd = true;
    	}
    
    	// Returns if the word is in the trie.
    	public boolean search(String word) {
    		if (word == null || word.length() == 0) {
    			return false;
    		}
    		TrieNode node = root;
    		char[] letters = word.toCharArray();
    		for (int i = 0; i < word.length(); i++) {
    			int pos = letters[i] - 'a';
    			if (node.son[pos] != null) {
    				node = node.son[pos];
    			} else {
    				return false;
    			}
    		}
    		return node.isEnd;
    	}
    
    	// Returns if there is any word in the trie
    	// that starts with the given prefix.
    	public boolean startsWith(String prefix) {
    		if (prefix == null || prefix.length() == 0) {
    			return false;
    		}
    		TrieNode node = root;
    		char[] letters = prefix.toCharArray();
    		for (int i = 0; i < prefix.length(); i++) {
    			int pos = letters[i] - 'a';
    			if (node.son[pos] != null) {
    				node = node.son[pos];
    			} else {
    				return false;
    			}
    		}
    		return true;
    	}
    }
    
  • 相关阅读:
    telnet模拟http訪问
    network: Android 网络推断(wifi、3G与其它)
    Cocos2d-x学习笔记(19)(TestCpp源代码分析-3)
    Thinkphp编辑器扩展类kindeditor用法
    逛自己的微博,回想以前的那个“我”
    微信生成二维码
    [C++]四种方式求解最大子序列求和问题
    Android 颜色渲染(二) 颜色区域划分原理与实现思路
    Android 颜色渲染(一) 颜色选择器 ColorPickerDialog剖析
    Android 图标上面添加提醒(二)使用开源UI类库 Viewbadger
  • 原文地址:https://www.cnblogs.com/tonyluis/p/4564425.html
Copyright © 2011-2022 走看看