Go语言LeetCode 682. 棒球比赛题解

不晚
不晚
发布时间:2026-10-15| 4人浏览过
原创

LeetCode 682题要求模拟一场特殊赛制的棒球比赛,根据操作数组ops计算最终得分总和。操作包括记录整数分值、撤销上次记录(C)、双倍上次得分(D)以及将前两次有效得分相加(+)。解决此问题的关键在于维护一个有序的历史得分序列,利用栈结构可以高效地处理最新状态的读写与修改,从而在线性时间内完成计算。

题目描述

你需要扮演一名棒球比赛的记录员。比赛由若干回合组成,过去的得分可能会影响后续回合的得分。初始记录为空。给定一个操作字符串列表 ops,其中包含以下四种规则:

  • 整数 x:表示本回合获得新分数 x,直接记录。
  • "+":表示本回合新获得的得分是前两次得分的总和。题目保证执行此操作时至少已有两个有效分数。
  • "D":表示本回合新获得的得分是前一次得分的两倍。题目保证执行此操作时至少已有一个有效分数。
  • "C":表示前一次得分无效,需从记录中移除。题目保证执行此操作时至少已有一个有效分数。

请返回所有有效得分的总和。

第1步:理解示例逻辑

以输入 ops = ["5", "2", "C", "D", "+"] 为例,逐步演示栈的变化过程:

  1. "5":记录加 5,当前记录为 [5]。
  2. "2":记录加 2,当前记录为 [5, 2]。
  3. "C":使最后一次得分(2)无效并移除,当前记录为 [5]。
  4. "D":新得分是上一次(5)的两倍,即 10。记录变为 [5, 10]。
  5. "+":新得分是前两次(5 和 10)的和,即 15。记录变为 [5, 10, 15]。

最终总和为 $5 + 10 + 15 = 30$。

第2步:分析操作约束

  • 长度限制:ops 的长度在 1 到 1000 之间。
  • 数值范围:整型分数在 $[-3 \times 10^4, 3 \times 10^4]$ 之间。
  • 前置条件:对于 "D" 和 "C" 操作,栈内至少有1个元素;对于 "+" 操作,栈内至少有2个元素。

解题思路

由于每次操作都依赖于历史记录的最新状态(如最近一次、最近两次得分),且涉及插入、删除末尾元素等操作,**栈(Stack)** 是最符合直觉的数据结构。我们可以使用一个切片来模拟栈的行为:

  1. 初始化栈:创建一个空的整型切片 stack,用于存储历史得分。
  2. 遍历操作数组:逐个读取 ops 中的字符串。
  3. 分类处理:
    • 若为 "C":执行出栈操作(丢弃最后一个元素)。
    • 若为 "D":读取栈顶元素,乘以2后入栈。
    • 若为 "+":读取栈顶元素和次栈顶元素,求和后作为新元素入栈。
    • 其他情况(数字):转换为整数后直接入栈。
  4. 计算总和:遍历结束后,累加栈中所有元素的值即为结果。

Go 语言 AC 代码

以下是基于上述逻辑的 Go 语言实现。使用标准库的切片模拟栈,配合 slices.Sort 或手动遍历求和均可,此处采用最直观的遍历求和方式。

package main

import (
	"strconv"
)

func calPoints(ops []string) int {
	// 使用切片模拟栈
	stack := []int{}

	for _, op := range ops {
		switch op {
		case "C":
			// 移除最后一条记录
			if len(stack) > 0 {
				stack = stack[:len(stack)-1]
			}
		case "D":
			// 新得分为上次得分的两倍
			lastScore := stack[len(stack)-1]
			stack = append(stack, lastScore*2)
		case "+":
			// 新得分为前两次得分之和
			// 因为保证了至少有两个元素,所以安全访问
			top := stack[len(stack)-1]
			secondTop := stack[len(stack)-2]
			stack = append(stack, top+secondTop)
		default:
			// 普通整数分数
			val, err := strconv.Atoi(op)
			if err == nil {
				stack = append(stack, val)
			}
		}
	}

	// 计算总和
	sum := 0
	for _, score := range stack {
		sum += score
	}
	return sum
}

复杂度分析

  • 时间复杂度:O(N),其中 N 是 ops 的长度。我们只需遍历数组一次,切片操作和加法运算均为 O(1)。
  • 空间复杂度:O(N),栈的大小最多为 N,用于存储每次操作后的得分状态。

关键点总结

  • 数据结构选择:LIFO(后进先出)特性完美契合“撤销”和“参考最近记录”的需求。
  • 边界检查:虽然题目保证数据合法性,但在实际开发中,访问 stack[len-1] 前应确保 len > 0。
  • 类型转换:输入的分数为字符串,使用 strconv.Atoi 安全转换,非数字字符默认为错误但题目限定只有特定命令。

以上就是Go语言LeetCode 682. 棒球比赛题解的详细内容,更多关于Go语言算法题解的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。