-
Notifications
You must be signed in to change notification settings - Fork 0
/
FindSecretWord.java
137 lines (124 loc) · 4.72 KB
/
FindSecretWord.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import java.util.ArrayList;
import java.util.List;
public class FindSecretWord {
/**
* LeetCode 843:
*
* This is an interactive problem.
*
* You are given an array of unique strings wordlist where wordlist[i] 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 exactly 10 guesses to guess the word. At the end of any number of calls, if you have made 10 or fewer calls to Master.guess and at least one of these guesses was secret, then you pass the test case.
*
*
*
* Example 1:
*
* Input: secret = "acckzz", wordlist = ["acckzz","ccbazz","eiowzz","abcczz"], numguesses = 10
* Output: You guessed the secret word correctly.
* 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.
*
* Example 2:
*
* Input: secret = "hamada", wordlist = ["hamada","khaled"], numguesses = 10
* Output: You guessed the secret word correctly.
*
*
* Constraints:
*
* 1 <= wordlist.length <= 100
* wordlist[i].length == 6
* wordlist[i] consist of lowercase English letters.
* All the strings of wordlist are unique.
* secret exists in wordlist.
* numguesses == 10
*
*
*
**
*
* // 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 Master {
// fake code for testing
public int guess(String word) {
return 6;
}
}
// Sol1: pick first
public void findSecretWord(String[] wordlist, Master master) {
String word = wordlist[0];
int matches = master.guess(word);
if (matches == 6) {
return;
}
List<String> wordlist2 = new ArrayList<>();
for (int i = 1; i < wordlist.length; i++) {
String curWord = wordlist[i];
if (match(curWord, word) == matches) {
wordlist2.add(curWord);
}
}
findSecretWord(wordlist2.toArray(new String[wordlist2.size()]), master);
}
private int match(String word1, String word2) {
char[] chars1 = word1.toCharArray();
char[] chars2 = word2.toCharArray();
int matches = 0;
for (int i = 0; i < 6; i++) {
matches += (chars1[i] == chars2[i] ? 1 : 0);
}
return matches;
}
// Sol2: Maxmin
// https://leetcode.com/problems/guess-the-word/discuss/133862/Random-Guess-and-Minimax-Guess-with-Comparison
public void findSecretWord2(String[] wordlist, Master master) {
int[][] charFreq = new int[6][26];
for (String word : wordlist) {
char[] charArr = word.toCharArray();
for (int i = 0; i < 6; i++) {
charFreq[i][charArr[i] - 'a'] += 1;
}
}
for (int i = 0; i < 10; i++) {
// Pick the most representative word
int maxScore = 0;
String guess = "";
for (String word : wordlist) {
char[] charArr = word.toCharArray();
int curScore = 0;
for (int j = 0; j < 6; j++) {
curScore += charFreq[j][charArr[j] - 'a'];
}
if (curScore > maxScore) {
maxScore = curScore;
guess = word;
}
}
int matches = master.guess(guess);
if (matches == 6) {
return;
}
List<String> wordlist2 = new ArrayList<>();
for (String word : wordlist) {
if (match(guess, word) == matches)
wordlist2.add(word);
}
wordlist = wordlist2.toArray(new String[wordlist2.size()]);
}
}
}