Skip to content

Commit 5ab692e

Browse files
committed
update 399 java, cheatsheet
1 parent c460584 commit 5ab692e

File tree

3 files changed

+296
-17
lines changed

3 files changed

+296
-17
lines changed

doc/cheatsheet/dfs.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,95 @@ class Solution:
744744
return -1.0
745745
```
746746

747+
```java
748+
// java
749+
// V1
750+
// IDEA: DFS
751+
// https://leetcode.com/problems/evaluate-division/solutions/3543256/image-explanation-easiest-concise-comple-okpu/
752+
public double[] calcEquation_1(List<List<String>> equations, double[] values, List<List<String>> queries) {
753+
HashMap<String, HashMap<String, Double>> gr = buildGraph(equations, values);
754+
double[] finalAns = new double[queries.size()];
755+
756+
for (int i = 0; i < queries.size(); i++) {
757+
String dividend = queries.get(i).get(0);
758+
String divisor = queries.get(i).get(1);
759+
760+
/** NOTE !!!
761+
*
762+
* either dividend nor divisor NOT in graph, return -1.0 directly
763+
*/
764+
if (!gr.containsKey(dividend) || !gr.containsKey(divisor)) {
765+
finalAns[i] = -1.0;
766+
} else {
767+
768+
/** NOTE !!!
769+
*
770+
* we use `vis` to check if element already visited
771+
* (to avoid repeat accessing)
772+
* `vis` init again in every loop
773+
*/
774+
775+
HashSet<String> vis = new HashSet<>();
776+
/**
777+
* NOTE !!!
778+
*
779+
* we init `ans` and pass it to dfs method
780+
* (but dfs method return NOTHING)
781+
* -> `ans` is init, and pass into dfs,
782+
* -> so `ans` value is updated during dfs recursion run
783+
* -> and after dfs run completed, we get the result `ans` value
784+
*/
785+
double[] ans = { -1.0 };
786+
double temp = 1.0;
787+
dfs(dividend, divisor, gr, vis, ans, temp);
788+
finalAns[i] = ans[0];
789+
}
790+
}
791+
792+
return finalAns;
793+
}
794+
795+
/** NOTE !!! below dfs method */
796+
public void dfs(String node, String dest, HashMap<String, HashMap<String, Double>> gr, HashSet<String> vis,
797+
double[] ans, double temp) {
798+
799+
/** NOTE !!! we use `vis` to check if element already visited */
800+
if (vis.contains(node))
801+
return;
802+
803+
vis.add(node);
804+
if (node.equals(dest)) {
805+
ans[0] = temp;
806+
return;
807+
}
808+
809+
for (Map.Entry<String, Double> entry : gr.get(node).entrySet()) {
810+
String ne = entry.getKey();
811+
double val = entry.getValue();
812+
/** NOTE !!! update temp as `temp * val` */
813+
dfs(ne, dest, gr, vis, ans, temp * val);
814+
}
815+
}
816+
817+
public HashMap<String, HashMap<String, Double>> buildGraph(List<List<String>> equations, double[] values) {
818+
HashMap<String, HashMap<String, Double>> gr = new HashMap<>();
819+
820+
for (int i = 0; i < equations.size(); i++) {
821+
String dividend = equations.get(i).get(0);
822+
String divisor = equations.get(i).get(1);
823+
double value = values[i];
824+
825+
gr.putIfAbsent(dividend, new HashMap<>());
826+
gr.putIfAbsent(divisor, new HashMap<>());
827+
828+
gr.get(dividend).put(divisor, value);
829+
gr.get(divisor).put(dividend, 1.0 / value);
830+
}
831+
832+
return gr;
833+
}
834+
```
835+
747836
### 2-10) Most Frequent Subtree Sum
748837
```python
749838
# LC 508 Most Frequent Subtree Sum

doc/cheatsheet/java_trick.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,28 @@ Integer [] arr2 = list2.toArray(new Integer[list2.size()]); // NOTE here !!!
8888

8989
- https://javaguide.cn/java/collection/java-collection-precautions-for-use.html#%E6%95%B0%E7%BB%84%E8%BD%AC%E9%9B%86%E5%90%88
9090

91+
92+
### 0-0-2) HashMap append to value if key existed/Not existed
93+
94+
```java
95+
// java
96+
// LC 399
97+
98+
HashMap<String, HashMap<String, Double>> gr = new HashMap<>();
99+
100+
for (int i = 0; i < equations.size(); i++) {
101+
String dividend = equations.get(i).get(0);
102+
String divisor = equations.get(i).get(1);
103+
double value = values[i];
104+
105+
gr.putIfAbsent(dividend, new HashMap<>());
106+
gr.putIfAbsent(divisor, new HashMap<>());
107+
108+
gr.get(dividend).put(divisor, value);
109+
gr.get(divisor).put(dividend, 1.0 / value);
110+
}
111+
```
112+
91113
### 1-0) String to Char array
92114
```java
93115
// java

leetcode_java/src/main/java/LeetCodeJava/DFS/EvaluateDivision.java

Lines changed: 185 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
// https://leetcode.com/problems/evaluate-division/description/
44

5+
import dev.workspace6;
6+
57
import java.util.*;
68

79
/**
@@ -57,19 +59,138 @@
5759
*/
5860
public 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

Comments
 (0)