22
33// https://leetcode.com/problems/evaluate-division/description/
44
5+ import dev .workspace6 ;
6+
57import java .util .*;
68
79/**
5759 */
5860public class EvaluateDivision {
5961 // V0
60- // TODO: implement
61- // public double[] calcEquation(List<List<String>> equations, double[] values, List<List<String>> queries) {
62+ // TODO: fix below
63+ // private class EquationRes{
64+ // // attr
65+ // String variable;
66+ // Double result;
67+ //
68+ // public Double getResult() {
69+ // return result;
70+ // }
71+ //
72+ // public String getVariable() {
73+ // return variable;
74+ // }
75+ //
76+ // // constructor
77+ // EquationRes(String variable, Double result){
78+ // this.variable = variable;
79+ // this.result = result;
80+ // }
81+ // }
82+ //
83+ // // init relation
84+ // Map<String, List<workspace6.EquationRes>> relations = new HashMap();
85+ // //double[] res = new double[];
86+ //
87+ // public double[] calcEquation(
88+ //
89+ // List<List<String>> equations, double[] values, List<List<String>> queries) {
90+ //
91+ // // build
92+ // buildRelation(equations, values);
93+ // // get
94+ // double[] res = new double[queries.size()];
95+ // for(int i = 0; i < queries.size(); i++){
96+ // res[i] = getResult(queries.get(i), 1);
97+ // }
98+ //
99+ // System.out.println(">>> res = " + res);
100+ //
101+ // return res;
102+ // }
103+ //
104+ // // dfs
105+ // private double getResult(List<String> queries, double res){
106+ // // check if in list
107+ // String firstVal = queries.get(0);
108+ // String secondVal = queries.get(1);
109+ // if (!this.relations.containsKey(firstVal) || !this.relations.containsKey(secondVal)){
110+ // return -1.0;
111+ // }
112+ //
113+ // //double res = 1;
114+ // //List<EquationRes> x = this.relations.get(firstVal);
115+ // for(workspace6.EquationRes equationRes: this.relations.get(firstVal)){
116+ // res = res * equationRes.result;
117+ //
118+ //
119+ // }
120+ //
121+ // return res;
122+ // }
123+ //
124+ // // build relation
125+ // private void buildRelation(List<List<String>> equations, double[] values){
126+ // for(int i = 0; i < equations.size(); i++){
127+ // List<String> equation = equations.get(i);
128+ // String firstVal = equation.get(0);
129+ // String secondVal = equation.get(1);
130+ //
131+ // workspace6.EquationRes equationRes = new workspace6.EquationRes(secondVal, values[i]);
132+ //
133+ // List<workspace6.EquationRes> equationAndRes = new ArrayList<>();
134+ // if (this.relations.containsKey(firstVal)){
135+ // equationAndRes = this.relations.get(firstVal);
136+ // }
137+ //
138+ // this.relations.put(firstVal, equationAndRes);
139+ // }
62140//
63141// }
64-
65142
66143 // V1
67-
68- // V2
69144 // IDEA: DFS
70145 // https://leetcode.com/problems/evaluate-division/solutions/3543256/image-explanation-easiest-concise-comple-okpu/
146+ public double [] calcEquation_1 (List <List <String >> equations , double [] values , List <List <String >> queries ) {
147+ HashMap <String , HashMap <String , Double >> gr = buildGraph (equations , values );
148+ double [] finalAns = new double [queries .size ()];
149+
150+ for (int i = 0 ; i < queries .size (); i ++) {
151+ String dividend = queries .get (i ).get (0 );
152+ String divisor = queries .get (i ).get (1 );
153+
154+ /** NOTE !!!
155+ *
156+ * either dividend nor divisor NOT in graph, return -1.0 directly
157+ */
158+ if (!gr .containsKey (dividend ) || !gr .containsKey (divisor )) {
159+ finalAns [i ] = -1.0 ;
160+ } else {
161+
162+ /** NOTE !!!
163+ *
164+ * we use `vis` to check if element already visited
165+ * (to avoid repeat accessing)
166+ * `vis` init again in every loop
167+ */
168+
169+ HashSet <String > vis = new HashSet <>();
170+ /**
171+ * NOTE !!!
172+ *
173+ * we init `ans` and pass it to dfs method
174+ * (but dfs method return NOTHING)
175+ * -> `ans` is init, and pass into dfs,
176+ * -> so `ans` value is updated during dfs recursion run
177+ * -> and after dfs run completed, we get the result `ans` value
178+ */
179+ double [] ans = { -1.0 };
180+ double temp = 1.0 ;
181+ dfs (dividend , divisor , gr , vis , ans , temp );
182+ finalAns [i ] = ans [0 ];
183+ }
184+ }
185+
186+ return finalAns ;
187+ }
188+
189+ /** NOTE !!! below dfs method */
71190 public void dfs (String node , String dest , HashMap <String , HashMap <String , Double >> gr , HashSet <String > vis ,
72191 double [] ans , double temp ) {
192+
193+ /** NOTE !!! we use `vis` to check if element already visited */
73194 if (vis .contains (node ))
74195 return ;
75196
@@ -82,6 +203,7 @@ public void dfs(String node, String dest, HashMap<String, HashMap<String, Double
82203 for (Map .Entry <String , Double > entry : gr .get (node ).entrySet ()) {
83204 String ne = entry .getKey ();
84205 double val = entry .getValue ();
206+ /** NOTE !!! update temp as `temp * val` */
85207 dfs (ne , dest , gr , vis , ans , temp * val );
86208 }
87209 }
@@ -104,26 +226,71 @@ public HashMap<String, HashMap<String, Double>> buildGraph(List<List<String>> eq
104226 return gr ;
105227 }
106228
229+ // V2
230+ // IDEA: DFS (gpt)
107231 public double [] calcEquation_2 (List <List <String >> equations , double [] values , List <List <String >> queries ) {
108- HashMap <String , HashMap <String , Double >> gr = buildGraph (equations , values );
109- double [] finalAns = new double [queries .size ()];
232+ // Build the graph
233+ Map <String , Map <String , Double >> graph = new HashMap <>();
234+ for (int i = 0 ; i < equations .size (); i ++) {
235+ String a = equations .get (i ).get (0 );
236+ String b = equations .get (i ).get (1 );
237+ double value = values [i ];
238+
239+ graph .putIfAbsent (a , new HashMap <>());
240+ graph .putIfAbsent (b , new HashMap <>());
241+
242+ graph .get (a ).put (b , value );
243+ graph .get (b ).put (a , 1.0 / value );
244+ }
110245
246+ // Process each query
247+ double [] results = new double [queries .size ()];
111248 for (int i = 0 ; i < queries .size (); i ++) {
112- String dividend = queries .get (i ).get (0 );
113- String divisor = queries .get (i ).get (1 );
249+ String c = queries .get (i ).get (0 );
250+ String d = queries .get (i ).get (1 );
114251
115- if (!gr .containsKey (dividend ) || !gr .containsKey (divisor )) {
116- finalAns [i ] = -1.0 ;
252+ // If either node is not in the graph, result is -1.0
253+ if (!graph .containsKey (c ) || !graph .containsKey (d )) {
254+ results [i ] = -1.0 ;
255+ } else if (c .equals (d )) {
256+ // If nodes are the same, result is 1.0
257+ results [i ] = 1.0 ;
117258 } else {
118- HashSet <String > vis = new HashSet <>();
119- double [] ans = { -1.0 };
120- double temp = 1.0 ;
121- dfs (dividend , divisor , gr , vis , ans , temp );
122- finalAns [i ] = ans [0 ];
259+ // Use DFS to find the result
260+ Set <String > visited = new HashSet <>();
261+ results [i ] = dfs (graph , c , d , 1.0 , visited );
123262 }
124263 }
125264
126- return finalAns ;
265+ return results ;
266+ }
267+
268+ private double dfs (Map <String , Map <String , Double >> graph , String current , String target , double value ,
269+ Set <String > visited ) {
270+ // If we reach the target, return the current value
271+ if (current .equals (target )) {
272+ return value ;
273+ }
274+
275+ // Mark the current node as visited
276+ visited .add (current );
277+
278+ // Explore neighbors
279+ for (Map .Entry <String , Double > neighbor : graph .get (current ).entrySet ()) {
280+ String nextNode = neighbor .getKey ();
281+ double weight = neighbor .getValue ();
282+
283+ if (!visited .contains (nextNode )) {
284+ double result = dfs (graph , nextNode , target , value * weight , visited );
285+ if (result != -1.0 ) {
286+ return result ;
287+ }
288+ }
289+ }
290+
291+ // Backtrack
292+ visited .remove (current );
293+ return -1.0 ;
127294 }
128295
129296 // V3
@@ -262,4 +429,5 @@ public double dfs(String src, String dest, Set<String> visited, Map<String, Map<
262429//
263430// return -1.0;
264431// }
432+
265433}
0 commit comments