LeetCode //C - 399. Evaluate Division

399. Evaluate Division

You are given an array of variable pairs equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string that represents a single variable.

You are also given some queries, where queries[j] = [Cj, Dj] represents the jth query where you must find the answer for Cj / Dj = ?.

Return the answers to all queries. If a single answer cannot be determined, return -1.0.

Note: The input is always valid. You may assume that evaluating the queries will not result in division by zero and that there is no contradiction.

Note: The variables that do not occur in the list of equations are undefined, so the answer cannot be determined for them.
 

Example 1:

Input: equations = [[“a”,“b”],[“b”,“c”]], values = [2.0,3.0], queries = [[“a”,“c”],[“b”,“a”],[“a”,“e”],[“a”,“a”],[“x”,“x”]]
Output: [6.00000,0.50000,-1.00000,1.00000,-1.00000]
Explanation:
Given: a / b = 2.0, b / c = 3.0
queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ?
return: [6.0, 0.5, -1.0, 1.0, -1.0 ]
note: x is undefined => -1.0

Example 2:

Input: equations = [[“a”,“b”],[“b”,“c”],[“bc”,“cd”]], values = [1.5,2.5,5.0], queries = [[“a”,“c”],[“c”,“b”],[“bc”,“cd”],[“cd”,“bc”]]
Output: [3.75000,0.40000,5.00000,0.20000]

Example 3:

Input: equations = [[“a”,“b”]], values = [0.5], queries = [[“a”,“b”],[“b”,“a”],[“a”,“c”],[“x”,“y”]]
Output: [0.50000,2.00000,-1.00000,-1.00000]

Constraints:
  • 1 <= equations.length <= 20
  • equations[i].length == 2
  • 1 <= Ai.length, Bi.length <= 5
  • values.length == equations.length
  • 0.0 < values[i] <= 20.0
  • 1 <= queries.length <= 20
  • queries[i].length == 2
  • 1 <= Cj.length, Dj.length <= 5
  • Ai, Bi, Cj, Dj consist of lower case English letters and digits.

From: LeetCode
Link: 399. Evaluate Division


Solution:

Ideas:

1. Graph Construction:

  • A directed graph is constructed where each node represents a variable, and each directed edge represents a division equation between two variables.
  • Each equation A/B=k is represented as two directed edges in the graph, one from A to B with weight k, and another from B to A with weight 1/k.

2. Graph Representation:

  • The graph is represented using an adjacency list, where each node has a list of adjacent nodes along with the corresponding edge weights.
  • The graph is stored in a Graph struct, which contains an array of Node pointers (nodes), the current number of nodes in the graph (size), and the maximum number of nodes the graph can hold (maxSize).

3. Query Processing:

  • For each query C/D, a Depth-First Search (DFS) is performed to find a path from node C to node D in the graph.
  • If a path is found, the result of the query is computed by multiplying the weights of the edges along the path.
  • If no path is found, the result of the query is −1.0.

4. Detail Workflow:

  • Initialization: A graph is created with a maximum size of 2×equationsSize to accommodate all unique variables in the equations.
  • Edge Addition: For each equation, two edges are added to the graph: one for the equation itself and another for its reciprocal.
  • Query Answering: For each query, the DFS is performed to find the result of the division.
  • Memory Deallocation: After processing all queries, the allocated memory should be freed to avoid memory leaks.

5. DFS Detail:

  • DFS starts from the source node (numerator) and tries to reach the destination node (denominator) by exploring each path recursively.
  • A visited array is used to keep track of the visited nodes during the DFS to avoid cycles.
  • If the destination node is reached, the DFS returns the product of the edge weights along the path.
  • If the destination node is not reached, the DFS returns −1.0.
Code:
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
typedef struct Node {
    char* var;
    double value;
    struct Node* next;
} Node;

typedef struct Graph {
    Node** nodes;
    int size;
    int maxSize;
} Graph;

Graph* createGraph(int size) {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->nodes = (Node**)calloc(size, sizeof(Node*));
    graph->size = 0;
    graph->maxSize = size;
    return graph;
}

int getIndex(Graph* graph, char* var) {
    for (int i = 0; i < graph->size; i++) {
        if (graph->nodes[i] && strcmp(graph->nodes[i]->var, var) == 0) return i;
    }
    return -1;
}

void addEdge(Graph* graph, char* src, char* dest, double value) {
    int srcIndex = getIndex(graph, src);
    if (srcIndex == -1) {
        srcIndex = graph->size++;
        graph->nodes[srcIndex] = (Node*)malloc(sizeof(Node));
        graph->nodes[srcIndex]->var = src;
        graph->nodes[srcIndex]->value = 1.0;
        graph->nodes[srcIndex]->next = NULL;
    }
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->var = dest;
    newNode->value = value;
    newNode->next = graph->nodes[srcIndex]->next;
    graph->nodes[srcIndex]->next = newNode;
}

double dfs(Graph* graph, char* src, char* dest, double product, int* visited) {
    int index = getIndex(graph, src);
    if (index == -1) return -1.0;
    if (strcmp(src, dest) == 0) return product;
    visited[index] = 1;
    for (Node* node = graph->nodes[index]->next; node; node = node->next) {
        int nextIndex = getIndex(graph, node->var);
        if (nextIndex != -1 && !visited[nextIndex]) {
            double result = dfs(graph, node->var, dest, product * node->value, visited);
            if (result != -1.0) return result;
        }
    }
    return -1.0;
}

double* calcEquation(char *** equations, int equationsSize, int* equationsColSize, double* values, int valuesSize, char *** queries, int queriesSize, int* queriesColSize, int* returnSize) {
    Graph* graph = createGraph(equationsSize * 2);
    for (int i = 0; i < equationsSize; i++) {
        addEdge(graph, equations[i][0], equations[i][1], values[i]);
        addEdge(graph, equations[i][1], equations[i][0], 1.0 / values[i]);
    }
    double* results = (double*)malloc(sizeof(double) * queriesSize);
    *returnSize = queriesSize;
    for (int i = 0; i < queriesSize; i++) {
        int* visited = (int*)calloc(graph->size, sizeof(int));
        results[i] = dfs(graph, queries[i][0], queries[i][1], 1.0, visited);
        free(visited);
    }
    // Don't forget to free the graph memory here
    return results;
}

你可能感兴趣的:(LeetCode,leetcode,c语言,算法)