|
58 | 58 | * |
59 | 59 | */ |
60 | 60 | public class EvaluateDivision { |
| 61 | + |
61 | 62 | // V0 |
62 | 63 | // TODO: fix below |
63 | 64 | // private class EquationRes{ |
@@ -361,6 +362,172 @@ public double dfs(String src, String dest, Set<String> visited, Map<String, Map< |
361 | 362 | return -1.0; |
362 | 363 | } |
363 | 364 |
|
| 365 | + // V4 |
| 366 | + // IDEA: UNION FIND (gpt) |
| 367 | + class UnionFind { |
| 368 | + private Map<String, String> parent; |
| 369 | + private Map<String, Double> ratio; |
| 370 | + |
| 371 | + public UnionFind() { |
| 372 | + this.parent = new HashMap<>(); |
| 373 | + this.ratio = new HashMap<>(); |
| 374 | + } |
| 375 | + |
| 376 | + // Finds the root of a node and applies path compression |
| 377 | + public String find(String x) { |
| 378 | + if (!parent.containsKey(x)) { |
| 379 | + parent.put(x, x); |
| 380 | + ratio.put(x, 1.0); |
| 381 | + } |
| 382 | + |
| 383 | + if (!x.equals(parent.get(x))) { |
| 384 | + String originalParent = parent.get(x); |
| 385 | + parent.put(x, find(originalParent)); |
| 386 | + ratio.put(x, ratio.get(x) * ratio.get(originalParent)); |
| 387 | + } |
| 388 | + |
| 389 | + return parent.get(x); |
| 390 | + } |
| 391 | + |
| 392 | + // Union two nodes with the given value |
| 393 | + public void union(String x, String y, double value) { |
| 394 | + String rootX = find(x); |
| 395 | + String rootY = find(y); |
| 396 | + |
| 397 | + if (!rootX.equals(rootY)) { |
| 398 | + parent.put(rootX, rootY); |
| 399 | + ratio.put(rootX, value * ratio.get(y) / ratio.get(x)); |
| 400 | + } |
| 401 | + } |
| 402 | + |
| 403 | + // Get the ratio between two nodes if they are connected |
| 404 | + public double isConnected(String x, String y) { |
| 405 | + if (!parent.containsKey(x) || !parent.containsKey(y)) { |
| 406 | + return -1.0; |
| 407 | + } |
| 408 | + |
| 409 | + String rootX = find(x); |
| 410 | + String rootY = find(y); |
| 411 | + |
| 412 | + if (!rootX.equals(rootY)) { |
| 413 | + return -1.0; |
| 414 | + } |
| 415 | + |
| 416 | + return ratio.get(x) / ratio.get(y); |
| 417 | + } |
| 418 | + } |
| 419 | + |
| 420 | + public double[] calcEquation_4(List<List<String>> equations, double[] values, List<List<String>> queries) { |
| 421 | + UnionFind uf = new UnionFind(); |
| 422 | + |
| 423 | + // Build the union-find structure |
| 424 | + for (int i = 0; i < equations.size(); i++) { |
| 425 | + String a = equations.get(i).get(0); |
| 426 | + String b = equations.get(i).get(1); |
| 427 | + double value = values[i]; |
| 428 | + uf.union(a, b, value); |
| 429 | + } |
| 430 | + |
| 431 | + // Process the queries |
| 432 | + double[] results = new double[queries.size()]; |
| 433 | + for (int i = 0; i < queries.size(); i++) { |
| 434 | + String c = queries.get(i).get(0); |
| 435 | + String d = queries.get(i).get(1); |
| 436 | + results[i] = uf.isConnected(c, d); |
| 437 | + } |
| 438 | + |
| 439 | + return results; |
| 440 | + } |
| 441 | + |
| 442 | + // V5 |
| 443 | + // IDEA: UNION FIND |
| 444 | + // https://leetcode.com/problems/evaluate-division/submissions/1498458088/ |
| 445 | +// private Map<String, Pair<String, Double>> parents = new HashMap<>(); |
| 446 | +// |
| 447 | +// public double[] calcEquation(List<List<String>> equations, double[] values, |
| 448 | +// List<List<String>> queries) { |
| 449 | +// // Step 1: build union groups |
| 450 | +// for (int i = 0; i < equations.size(); i++) { |
| 451 | +// List<String> equation = equations.get(i); |
| 452 | +// |
| 453 | +// String u = equation.get(0), v = equation.get(1); |
| 454 | +// double w = values[i]; |
| 455 | +// |
| 456 | +// union(u, v, w); |
| 457 | +// } |
| 458 | +// |
| 459 | +// // Step 2. try to make the query |
| 460 | +// double[] res = new double[queries.size()]; |
| 461 | +// for (int i = 0; i < queries.size(); i++) { |
| 462 | +// List<String> query = queries.get(i); |
| 463 | +// String u = query.get(0), v = query.get(1); |
| 464 | +// |
| 465 | +// // case 1: u or v never appear before |
| 466 | +// if (!parents.containsKey(u) || !parents.containsKey(v)) { |
| 467 | +// res[i] = -1.0; |
| 468 | +// continue; |
| 469 | +// } |
| 470 | +// |
| 471 | +// Pair<String, Double> uPair = find(u); |
| 472 | +// Pair<String, Double> vPair = find(v); |
| 473 | +// |
| 474 | +// String uParent = uPair.getKey(); |
| 475 | +// double uWeight = uPair.getValue(); |
| 476 | +// |
| 477 | +// String vParent = vPair.getKey(); |
| 478 | +// double vWeight = vPair.getValue(); |
| 479 | +// |
| 480 | +// if (!uParent.equals(vParent)) |
| 481 | +// // case 2: u & v NOT belong to the same group |
| 482 | +// res[i] = -1.0; |
| 483 | +// else |
| 484 | +// /* |
| 485 | +// * case 3: u & v belong to the same group <==> uPar == vPar |
| 486 | +// * Then we want to query u / v: |
| 487 | +// * |
| 488 | +// * Assuming we have: |
| 489 | +// * 1. u = uPar * uWei |
| 490 | +// * 2. v = vPar * vWei = uPar * vWei |
| 491 | +// * |
| 492 | +// * Thus u / v = uWei / vWei |
| 493 | +// */ |
| 494 | +// res[i] = uWeight / vWeight; |
| 495 | +// |
| 496 | +// } |
| 497 | +// return res; |
| 498 | +// } |
| 499 | +// |
| 500 | +// private Pair<String, Double> find(String u) { |
| 501 | +// if (!parents.containsKey(u)) { |
| 502 | +// parents.put(u, new Pair(u, 1.0)); |
| 503 | +// return parents.get(u); |
| 504 | +// } |
| 505 | +// |
| 506 | +// if (!parents.get(u).getKey().equals(u)) { |
| 507 | +// Pair<String, Double> uParentPair = parents.get(u); |
| 508 | +// Pair<String, Double> uGrandParentPair = find(uParentPair.getKey()); |
| 509 | +// |
| 510 | +// parents.put(u, new Pair(uGrandParentPair.getKey(), |
| 511 | +// uParentPair.getValue() * uGrandParentPair.getValue())); |
| 512 | +// } |
| 513 | +// return parents.get(u); |
| 514 | +// } |
| 515 | +// |
| 516 | +// private void union(String u, String v, Double w) { |
| 517 | +// Pair<String, Double> uPair = find(u); |
| 518 | +// Pair<String, Double> vPair = find(v); |
| 519 | +// |
| 520 | +// String uParent = uPair.getKey(); |
| 521 | +// double uWeight = uPair.getValue(); |
| 522 | +// |
| 523 | +// String vParent = vPair.getKey(); |
| 524 | +// double vWeight = vPair.getValue(); |
| 525 | +// |
| 526 | +// if (!uParent.equals(vParent)) { |
| 527 | +// parents.put(uParent, new Pair(vParent, vWeight / uWeight * w)); |
| 528 | +// } |
| 529 | +// } |
| 530 | + |
364 | 531 | // V4 |
365 | 532 | // IDEA: BFS |
366 | 533 | // https://leetcode.com/problems/evaluate-division/solutions/3543150/pythonjavacsimple-solutioneasy-to-unders-7uwo/ |
|
0 commit comments