3484. 设计电子表格
题目描述
电子表格是一个网格,它有 26 列(从 'A'
到 'Z'
)和指定数量的 rows
。每个单元格可以存储一个 0 到 105 之间的整数值。
请你实现一个 Spreadsheet
类:
Spreadsheet(int rows)
初始化一个具有 26 列(从'A'
到'Z'
)和指定行数的电子表格。所有单元格最初的值都为 0 。void setCell(String cell, int value)
设置指定单元格的值。单元格引用以"AX"
的格式提供(例如,"A1"
,"B10"
),其中字母表示列(从'A'
到'Z'
),数字表示从 1 开始的行号。void resetCell(String cell)
重置指定单元格的值为 0 。int getValue(String formula)
计算一个公式的值,格式为"=X+Y"
,其中X
和Y
要么 是单元格引用,要么非负整数,返回计算的和。
注意: 如果 getValue
引用一个未通过 setCell
明确设置的单元格,则该单元格的值默认为 0 。
示例 1:
输入:
["Spreadsheet", "getValue", "setCell", "getValue", "setCell", "getValue", "resetCell", "getValue"]
[[3], ["=5+7"], ["A1", 10], ["=A1+6"], ["B2", 15], ["=A1+B2"], ["A1"], ["=A1+B2"]]
输出:
[null, 12, null, 16, null, 25, null, 15]
解释
Spreadsheet spreadsheet = new Spreadsheet(3); // 初始化一个具有 3 行和 26 列的电子表格spreadsheet.getValue("=5+7"); // 返回 12 (5+7)
spreadsheet.setCell("A1", 10); // 设置 A1 为 10
spreadsheet.getValue("=A1+6"); // 返回 16 (10+6)
spreadsheet.setCell("B2", 15); // 设置 B2 为 15
spreadsheet.getValue("=A1+B2"); // 返回 25 (10+15)
spreadsheet.resetCell("A1"); // 重置 A1 为 0
spreadsheet.getValue("=A1+B2"); // 返回 15 (0+15)
提示:
1 <= rows <= 103
0 <= value <= 105
- 公式保证采用
"=X+Y"
格式,其中X
和Y
要么是有效的单元格引用,要么是小于等于105
的 非负 整数。 - 每个单元格引用由一个大写字母
'A'
到'Z'
和一个介于1
和rows
之间的行号组成。 - 总共 最多会对
setCell
、resetCell
和getValue
调用104
次。
解法
方法一:哈希表
我们用一个哈希表 $\textit{d}$ 来记录所有单元格的值,其中键为单元格引用,值为单元格的值。
调用 setCell
方法时,我们将单元格引用和值存入哈希表中。
调用 resetCell
方法时,我们将单元格引用从哈希表中删除。
调用 getValue
方法时,我们将公式分割成两个单元格引用,然后计算它们的值,最后返回它们的和。
时间复杂度 $(L)$,空间复杂度 $(L)$。其中 $L$ 为公式的长度。
Python3
class Spreadsheet:
def __init__(self, rows: int):
self.d = {}
def setCell(self, cell: str, value: int) -> None:
self.d[cell] = value
def resetCell(self, cell: str) -> None:
self.d.pop(cell, None)
def getValue(self, formula: str) -> int:
ans = 0
for cell in formula[1:].split("+"):
ans += int(cell) if cell[0].isdigit() else self.d.get(cell, 0)
return ans
# Your Spreadsheet object will be instantiated and called as such:
# obj = Spreadsheet(rows)
# obj.setCell(cell,value)
# obj.resetCell(cell)
# param_3 = obj.getValue(formula)
Java
class Spreadsheet {
private Map<String, Integer> d = new HashMap<>();
public Spreadsheet(int rows) {
}
public void setCell(String cell, int value) {
d.put(cell, value);
}
public void resetCell(String cell) {
d.remove(cell);
}
public int getValue(String formula) {
int ans = 0;
for (String cell : formula.substring(1).split("\\+")) {
ans += Character.isDigit(cell.charAt(0)) ? Integer.parseInt(cell)
: d.getOrDefault(cell, 0);
}
return ans;
}
}
/**
* Your Spreadsheet object will be instantiated and called as such:
* Spreadsheet obj = new Spreadsheet(rows);
* obj.setCell(cell,value);
* obj.resetCell(cell);
* int param_3 = obj.getValue(formula);
*/
C++
class Spreadsheet {
private:
unordered_map<string, int> d;
public:
Spreadsheet(int rows) {}
void setCell(string cell, int value) {
d[cell] = value;
}
void resetCell(string cell) {
d.erase(cell);
}
int getValue(string formula) {
int ans = 0;
stringstream ss(formula.substr(1));
string cell;
while (getline(ss, cell, '+')) {
if (isdigit(cell[0])) {
ans += stoi(cell);
} else {
ans += d.count(cell) ? d[cell] : 0;
}
}
return ans;
}
};
/**
* Your Spreadsheet object will be instantiated and called as such:
* Spreadsheet* obj = new Spreadsheet(rows);
* obj->setCell(cell,value);
* obj->resetCell(cell);
* int param_3 = obj->getValue(formula);
*/
Go
type Spreadsheet struct {
d map[string]int
}
func Constructor(rows int) Spreadsheet {
return Spreadsheet{d: make(map[string]int)}
}
func (this *Spreadsheet) SetCell(cell string, value int) {
this.d[cell] = value
}
func (this *Spreadsheet) ResetCell(cell string) {
delete(this.d, cell)
}
func (this *Spreadsheet) GetValue(formula string) int {
ans := 0
cells := strings.Split(formula[1:], "+")
for _, cell := range cells {
if val, err := strconv.Atoi(cell); err == nil {
ans += val
} else {
ans += this.d[cell]
}
}
return ans
}
/**
* Your Spreadsheet object will be instantiated and called as such:
* obj := Constructor(rows);
* obj.SetCell(cell,value);
* obj.ResetCell(cell);
* param_3 := obj.GetValue(formula);
*/
TypeScript
class Spreadsheet {
private d: Map<string, number>;
constructor(rows: number) {
this.d = new Map<string, number>();
}
setCell(cell: string, value: number): void {
this.d.set(cell, value);
}
resetCell(cell: string): void {
this.d.delete(cell);
}
getValue(formula: string): number {
let ans = 0;
const cells = formula.slice(1).split('+');
for (const cell of cells) {
ans += isNaN(Number(cell)) ? this.d.get(cell) || 0 : Number(cell);
}
return ans;
}
}
/**
* Your Spreadsheet object will be instantiated and called as such:
* var obj = new Spreadsheet(rows)
* obj.setCell(cell,value)
* obj.resetCell(cell)
* var param_3 = obj.getValue(formula)
*/