676. 实现一个魔法字典【中等题】【每日一题】
思路:【暴力寻找】
就是用暴力碰碰运气,实在是对字典树有点怵,比较逃避。
结果跟官解方法1的代码思路完全一致~
也不用设计特殊的数据结构,就用传入的数组即可。
遍历数组中每一个单词,将其与传入单词进行比较,如果确实只相差一个字母,那么说明搜索成功,返回true,如果数组中所有单词都比较了一遍都没有只差一个字母的单词,那么说明搜索失败,返回false。
代码:
class MagicDictionary {
String[] dict;
public MagicDictionary() {
}
public void buildDict(String[] dictionary) {
this.dict = dictionary;
}
public boolean search(String searchWord) {
for(String target : dict){
if(makeSure(searchWord,target)){
return true;
}
}
return false;
}
public boolean makeSure(String word,String target){
if(word.length() != target.length()){
return false;
}else{
int n = word.length(),cnt = 0;
for(int i = 0; i < n ; i++){
if(word.charAt(i) != target.charAt(i)){
cnt++;
}
}
return cnt == 1;
}
}
}
/**
* Your MagicDictionary object will be instantiated and called as such:
* MagicDictionary obj = new MagicDictionary();
* obj.buildDict(dictionary);
* boolean param_2 = obj.search(searchWord);
*/
剑指 Offer II 111. 计算除法【中等题】
思路:
对官解的方法一,建图+BFS做了详细注解。
代码:
class Solution {
public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
//记录变量个数
int v_num = 0;
Map<String,Integer> variables = new HashMap<>();
//记录等式个数
int n = equations.size();
//建表,将每个变量放入哈希表中,并以数字进行标记
for (List<String> equation : equations) {
String v1 = equation.get(0), v2 = equation.get(1);
if (!variables.containsKey(v1)) {
variables.put(v1, v_num++);
}
if (!variables.containsKey(v2)) {
variables.put(v2, v_num++);
}
}
//建图,对于每个点,存储其直接连接到的所有点及对应的权值
//权值表示的含义为: 比如说 a/b = 2.0 ,那么a的直接连接点为b,对应权值为2.0,b的直接连接点为a,对应权值为 1/2.0
List<Pair>[] edges = new List[v_num];
for (int i = 0; i < v_num; i++) {
edges[i] = new ArrayList<>();
}
for (int i = 0; i < n; i++) {
int v1 = variables.get(equations.get(i).get(0)),v2 = variables.get(equations.get(i).get(1));
edges[v1].add(new Pair(v2,values[i]));
edges[v2].add(new Pair(v1,1.0 / values[i]));
}
//尝试求出每条查询的答案
//记录查询个数
int query_num = queries.size();
//定义答案数组 用来存储每条查询的答案
double[] ans = new double[query_num];
//遍历每一条查询
for (int i = 0; i < query_num; i++) {
//得到当前查询为 query
List<String> query = queries.get(i);
//定义当前查询的结果为 result 默认值为 -1.0
double result = -1.0;
//记录当前查询第一个变量(被除数)q1,记录当前查询第二个变量(除数)q2
String q1 = query.get(0),q2 = query.get(1);
//只有变量表中同时存在q1和q2,当前查询才有答案,若不满足这个条件,则当前查询的答案即为默认值 -1.0
if (variables.containsKey(q1) && variables.containsKey(q2)){
//变量表中同时存在q1和q2,则求出答案
//记录q1的数字节点值为i1,q2的数字节点值为i2
int i1 = variables.get(q1),i2 = variables.get(q2);
//如果 i1 == i2 ,说明q1和q2变量相等,则答案为 1.0
if (i1 == i2){
result = 1.0;
}else {
//如果q1和q2变量不相等,则开启BFS搜索
//定义 节点队列 points,队列中的节点均与i1节点有连接
Queue<Integer> points = new LinkedList<>();
//将q1变量的节点值加入队列
points.offer(i1);
//定义暂存结果数组 ratios,用来存放 q1 / 其他变量 的值,那么当前查询的结果就可以表示为 ratios[i2]
double[] ratios = new double[v_num];
//ratios赋初值,全部为 -1.0
Arrays.fill(ratios,-1.0);
// q1 / q1 = 1.0
ratios[i1] = 1.0;
//当points不为空 且 ratios[i2] < 0 时,说明尚未搜索到i2节点与i1节点建立的连接(即尚未搜索到 q1/q2)
while(!points.isEmpty() && ratios[i2] < 0){
//拉取队列头部 记为 x
int x = points.poll();
//遍历所有与 节点x相连的节点及其对应的权值
for (Pair pair : edges[x]) {
//记录当前与x节点相连的节点为y
int y = pair.index;
//记录当前与x节点相连的权值为val,即 x = y * val
double val = pair.value;
//如果ratios[y] < 0,说明y节点尚未与 i1节点建立联系,则尝试将y节点与i1节点建立连接
//由于x节点已经与 i1节点建立连接,因此可以通过x将y与i1连接起来
if (ratios[y] < 0){
//ratios[y] = i1 / y ,而 i1 / x = ratios[x] ,x = y * val
//于是 ratios[y] = x * ratios[x] / y = y * val * ratios[x] / y = ratios[x] * val
ratios[y] = ratios[x] * val;
//此时y节点与i1节点建立连接,将其加入队列
points.offer(y);
}
}
}
//将当前查询的结果result 赋值为 ratios[i2]
result = ratios[i2];
}
}
//将当前查询的答案 ans[i]赋值为 result
ans[i] = result;
}
return ans;
}
}
class Pair {
int index;
double value;
Pair(int index,double value){
this.index = index;
this.value = value;
}
}