2020-11-05

11.05每日一题

127. 单词接龙

题目可以看作是从起点到终点,可以采用BFS的方法来解,同时,由于终点是已知的,可以用双向BFS来进行时间优化,如果直接建图,每一个单词需要和除他之外的单词进行比较,复杂度为O(n*wordLength),但是如果把单词都放到一个hash表中,那么复杂度就可以减到O(26 * wordLength),使用BFS需要两个辅助数据结构,一个是队列,存放当前层,一个是visited集合,存放遍历过的节点,防止死循环。

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    	//将数组放入hash表中
        Set<String> wordSet = new HashSet<>(wordList);
        if(wordSet.size() == 0 || !wordSet.contains(endWord)){
        	return 0;
        }
        wordSet.remove(beginWord);
        //定义辅助数据结构
        Queue<String> queue = new LinkedList<>();
        Set<String> visited = new HashSet<>();
        queue.add(beginWord);
        visited.add(beginWord);
        //BFS
        int step = 1;
        while(!queue.isEmpty()){
        	int currentSize = queue.size();
        	for(int i =0; i < currentSize; i++){
        		String currentWord = queue.poll();
        		if(func(currentWord, endWord, queue, visited, wordSet)){
        			return step + 1;
        		}
        	}
        	step++;
        }
        return 0;
    }
    boolean func(String currentWord, String endWord, Queue<String> queue, Set<String> visited, Set<String> wordSet){
    	char[] charArray = currentWord.toCharArray();
    	for(int i =0 ;i < endWord.length(); i++){
    		char originChar = charArray[i];
    		for(char k = 'a'; k <= 'z'; k++){
    			if(k == originChar){
    				continue;
    			}
    			charArray[i] = k;
    			String nextWord = String.valueOf(charArray);
    			if(wordSet.contains(nextWord)){
    				if(nextWord.equals(endWord)){
    					return true;
    				}
    				if(!visited.contains(nextWord)){
    					queue.add(nextWord);
    					visited.add(nextWord);
    				}
    			}
    		}
    		charArray[i] = originChar;
    	}
    	return false;
    }
}

测试上面的代码,发现需要80多ms,还是挺慢的,使用双向BFS优化可以大量的减少使用时间,每次BFS从较短的一方开始。

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
    	//将数组放入hash表中
    	Set<String> wordSet = new HashSet<>(wordList);
    	if(wordSet.size() == 0 || !wordSet.contains(endWord)){
    		return 0;
    	}
    	//构建辅助数据结构
    	Set<String> visited = new HashSet<>();
    	visited.add(beginWord);
    	visited.add(endWord);
    	Set<String> beginVisited = new HashSet<>();
    	beginVisited.add(beginWord);
    	Set<String> endVisited = new HashSet<>();
    	endVisited.add(endWord);
    	//双向BFS
    	int step = 1;
    	while(!beginVisited.isEmpty() && !endVisited.isEmpty()){
    		if(beginVisited.size() > endVisited.size()){
    			Set<String> tmp = beginVisited;
    			beginVisited = endVisited;
    			endVisited = tmp;
    		}
    		Set<String> nextLevelVisited = new HashSet<>();
    		for(String word : beginVisited){
    			if(func(word, endVisited, visited, wordSet, nextLevelVisited)){
    				return step + 1;
    			}
    		}
    		beginVisited = nextLevelVisited;
    		step++;
    	}
    	return 0;	
    }
    boolean func(String word, Set<String> endVisited, Set<String> visited, Set<String> wordSet, Set<String> nextLevelVisited){
    	char[] charArray = word.toCharString();
    	for(int i = 0; i < word.length(); i++){
    		char originChar = charArray[i];
    		for(char c = 'a'; c <= 'z'; c++){
    			if(originChar == c){
    				continue;
    			}
    			charArray[i] = c;
    			String nextWord = String.valueOf(charArray);
    			if(wordSet.contains(nextWord)){
    				if(endVisited.contains(nextWord)){
    					return true;
    				}
    				if(!visited.contains(nextWord)){
    					nextLevelVisited.add(nextWord);
    					visited.add(nextLevelVisited);
    				}
    			}
    		}
    		charArray[i] = originChar;
    	}
    	return false;
    }
}

在这里插入图片描述
速度可以提高很多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值