leetcode
leetcode 551 ~ 600
设计 Excel 求和公式

设计 Excel 求和公式

难度:

标签:

题目描述

代码结果

运行时间: 29 ms, 内存: 16.2 MB


/*
 * Leetcode 631: 设计 Excel 求和公式
 *
 * 题目思路:
 * 1. 我们需要设计一个 Excel 类,该类可以支持设置单元格的值和计算某个单元格的和。
 * 2. 使用一个二维数组来表示 Excel 表格。
 * 3. 提供 set 方法来设置单元格的值。
 * 4. 提供 sum 方法来计算某个单元格的和,可以传入单个单元格或范围。
 * 5. 使用哈希表来存储每个单元格的求和公式。
 */
 
import java.util.HashMap;
import java.util.Map;
import java.util.stream.IntStream;
 
class Excel {
    private int[][] cells;
    private Map<String, String[]> formulaMap;
 
    public Excel(int height, char width) {
        cells = new int[height + 1][width - 'A' + 1];
        formulaMap = new HashMap<>();
    }
 
    public void set(int row, char column, int val) {
        cells[row][column - 'A'] = val;
        formulaMap.remove(row + "_" + column); // 移除该单元格的公式
    }
 
    public int get(int row, char column) {
        return cells[row][column - 'A'];
    }
 
    public int sum(int row, char column, String[] strs) {
        int sum = IntStream.of(strs).mapToInt(str -> {
            if (str.contains(":")) { // 处理范围
                String[] range = str.split(":");
                int[] start = parsePosition(range[0]);
                int[] end = parsePosition(range[1]);
                return IntStream.rangeClosed(start[0], end[0]).flatMap(r ->
                    IntStream.rangeClosed(start[1], end[1]).map(c -> cells[r][c])
                ).sum();
            } else { // 处理单个单元格
                int[] pos = parsePosition(str);
                return cells[pos[0]][pos[1]];
            }
        }).sum();
        formulaMap.put(row + "_" + column, strs);
        cells[row][column - 'A'] = sum;
        return sum;
    }
 
    private int[] parsePosition(String str) {
        int row = Integer.parseInt(str.substring(1));
        int column = str.charAt(0) - 'A';
        return new int[]{row, column};
    }
}
 

解释

方法:

这个题解实现了一个简化版的Excel,支持设置单元格的值、获取单元格的值以及计算求和公式。主要思路如下: 1. 使用一个二维列表 `matrix` 来存储Excel表格中每个单元格的值。 2. 使用一个字典 `formulas` 来存储每个单元格的求和公式。 3. `set` 方法用于设置单元格的值,同时删除该单元格的求和公式(如果存在)。 4. `get` 方法用于获取单元格的值,如果该单元格有求和公式,则计算求和公式的结果。 5. `sum` 方法用于计算单元格的求和公式,将求和结果存储到对应单元格,并将求和公式存储到 `formulas` 中。 6. `get_cell_value` 方法用于获取单个单元格或单元格范围的值。 7. `evaluate_formula` 方法用于计算单元格的求和公式的结果。

时间复杂度:

O(nm)

空间复杂度:

O(nm)

代码细节讲解

🦆
在`Excel`类的`sum`方法中,如果在`numbers`参数中有重复的单元格,这些单元格的值是否会被重复计算?如果是,这种设计是否合理?
是的,在`Excel`类的`sum`方法中,如果`numbers`参数包含重复的单元格,这些单元格的值会被重复计算。这种设计可能是合理的,因为在某些情况下,用户可能故意希望某个单元格的值在求和时被计算多次。然而,这也可能导致不必要的计算和性能负担,特别是在处理大量数据时。因此,这种设计的合理性取决于具体应用场景和用户的需求。
🦆
给定`Excel`类的实现方式,`set`方法在删除求和公式后,是否也应该递归地更新依赖于该单元格的其他公式的值?
根据当前的实现,`set`方法在删除单元格的求和公式后并没有递归地更新依赖于该单元格的其他公式的值。这可能会导致依赖于该单元格的其他单元格的值变得不准确。理想情况下,应该实现一种机制来追踪和更新所有依赖于被修改单元格的公式,以确保数据的一致性和准确性。
🦆
在`get_cell_value`方法中处理范围时,如何处理单元格范围跨越多行和列的情况,特别是当输入的起始和结束列字符顺序相反(如`D1:A1`)时?
在当前的实现中,`get_cell_value`方法在处理单元格范围时没有考虑起始和结束列字符顺序相反的情况。为了正确处理这种情况,应该在计算范围时添加逻辑来确定起始和结束列的正确顺序。如果起始列大于结束列,应该交换它们的位置,确保列的遍历顺序是从小到大。同样的逻辑也应用于行。
🦆
你的`sum`方法会将公式存储在`formulas`字典中。请问如果一个单元格的求和公式被多次修改,`formulas`字典是如何处理这种情况的?
在`sum`方法中,每次调用时都会更新`formulas`字典中对应单元格的公式。这意味着,如果一个单元格的求和公式被多次修改,`formulas`字典会直接用新的公式覆盖旧的公式。这样的设计简化了管理公式的复杂度,但也意味着旧的公式信息会被丢失。

相关问题