Guess the Word

This problem is an *interactive problem* new to the LeetCode platform.

We are given a word list of unique words, each word is 6 letters long, and one word in this list is chosen as secret.

You may call master.guess(word) to guess a word.  The guessed word should have type string and must be from the original list with 6 lowercase letters.

This function returns an integer type, representing the number of exact matches (value and position) of your guess to the secret word.  Also, if your guess is not in the given wordlist, it will return -1 instead.

For each test case, you have 10 guesses to guess the word. At the end of any number of calls, if you have made 10 or less calls to master.guess and at least one of these guesses was the secret, you pass the testcase.

Besides the example test case below, there will be 5 additional test cases, each with 100 words in the word list.  The letters of each word in those testcases were chosen independently at random from 'a'to 'z', such that every word in the given word lists is unique.

Example 1:
Input: secret = "acckzz", wordlist = ["acckzz","ccbazz","eiowzz","abcczz"]

Explanation:

`master.guess("aaaaaa")` returns -1, because `"aaaaaa"` is not in wordlist.
`master.guess("acckzz")` returns 6, because `"acckzz"` is secret and has all 6 matches.
`master.guess("ccbazz")` returns 3, because` "ccbazz"` has 3 matches.
`master.guess("eiowzz")` returns 2, because `"eiowzz"` has 2 matches.
`master.guess("abcczz")` returns 4, because `"abcczz"` has 4 matches.

We made 5 calls to master.guess and one of them was the secret, so we pass the test case.

Thinking: This question is said to have a word array wordlist, where there is a word that needs to guess the secret word, there is now a function api guess, you can return the number of matches between the words and guess the target word. Now each test case there are 10 chances to guess the target word, if the number of api calls no more than 10 times, and guess the target word, then it can pass the test. First, due to the need as few call api, so that a call to a linear api for each word is not preferable, because if the last target word, and the word length of the array over 10, will fail. Such a case may be randomly selected word is detected, the call will be a number CNT api, indicates the number of words and a match between the current target word. Then how to do it? Needs to be filtered again array of words, to write a similar function api, it returns the number of matches between any two words, so that you can filter the entire array of words, because hidden in plain words of the target word with the current word to call match the return value must still cnt, of course, there will be other words that also returns cnt, but that's okay, still be able to filter out a large wave of unrelated words, repeat this step until exactly 6 cnt stop, because the title says a word length is 6,

The core idea: after a word is selected at random guess, because guess is more with the correct answer, then the word and then to scan all of the words, the same count == word of all the elected candidate, so you can not count kicked a lot of word, kicked off with the correct answer is not so match the words, and then continue the above steps until the count == 6, that is, until the word length of 6;

/**
 * // This is the Master's API interface.
 * // You should not implement it, or speculate about its implementation
 * interface Master {
 *     public int guess(String word) {}
 * }
 */
class Solution {
    public void findSecretWord(String[] wordlist, Master master) {
        if(wordlist == null || wordlist.length == 0) {
            return;
        }
        Random random = new Random();
        int count = 0;
        List<String> wlist = Arrays.asList(wordlist);
        
        for(int i = 0, cnt = 0; i < 10 && cnt < 6; i++) {
            int n = wlist.size();
            String word = wlist.get(random.nextInt(n));
            cnt = master.guess(word);
            
            List<String> newlist = new ArrayList<>();
            for(String candidate : wlist) {
                if(getDistance(candidate, word) == cnt) {
                    newlist.add(candidate);
                } 
            }
            wlist = newlist;
        }
    }
    
    private int getDistance(String word, String target) {
        int count = 0;
        for(int i = 0; i < word.length(); i++) {
            if(word.charAt(i) == target.charAt(i)) {
                count++;
            }
        }
        return count;
    }
}

 

Published 673 original articles · won praise 13 · views 180 000 +

Guess you like

Origin blog.csdn.net/u013325815/article/details/105221311