棒球比赛
描述
-
你现在是一场采用特殊赛制棒球比赛的记录员。这场比赛由若干回合组成,过去几回合的得分可能会影响以后几回合的得分。
-
比赛开始时,记录是空白的。你会得到一个记录操作的字符串列表 ops,其中 ops[i] 是你需要记录的第 i 项操作,ops 遵循下述规则:
- 整数 x - 表示本回合新获得分数 x
- “+” - 表示本回合新获得的得分是前两次得分的总和。题目数据保证记录此操作时前面总是存在两个有效的分数。
- “D” - 表示本回合新获得的得分是前一次得分的两倍。题目数据保证记录此操作时前面总是存在一个有效的分数。
- “C” - 表示前一次得分无效,将其从记录中移除。题目数据保证记录此操作时前面总是存在一个有效的分数。
-
请你返回记录中所有得分的总和。
示例 1
输入:ops = ["5","2","C","D","+"]
输出:30
解释:
"5" - 记录加 5 ,记录现在是 [5]
"2" - 记录加 2 ,记录现在是 [5, 2]
"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5].
"D" - 记录加 2 * 5 = 10 ,记录现在是 [5, 10].
"+" - 记录加 5 + 10 = 15 ,记录现在是 [5, 10, 15].
所有得分的总和 5 + 10 + 15 = 30
示例 2:
输入:ops = ["5","-2","4","C","D","9","+","+"]
输出:27
解释:
"5" - 记录加 5 ,记录现在是 [5]
"-2" - 记录加 -2 ,记录现在是 [5, -2]
"4" - 记录加 4 ,记录现在是 [5, -2, 4]
"C" - 使前一次得分的记录无效并将其移除,记录现在是 [5, -2]
"D" - 记录加 2 * -2 = -4 ,记录现在是 [5, -2, -4]
"9" - 记录加 9 ,记录现在是 [5, -2, -4, 9]
"+" - 记录加 -4 + 9 = 5 ,记录现在是 [5, -2, -4, 9, 5]
"+" - 记录加 9 + 5 = 14 ,记录现在是 [5, -2, -4, 9, 5, 14]
所有得分的总和 5 + -2 + -4 + 9 + 5 + 14 = 27
示例 3:
输入:ops = ["1"]
输出:1
提示
- 1 <= ops.length <= 1000
- ops[i] 为 “C”、“D”、“+”,或者一个表示整数的字符串。整数范围是 [-3 * 1 0 4 10^4 104, 3 * 1 0 4 10^4 104]
- 对于 “+” 操作,题目数据保证记录此操作时前面总是存在两个有效的分数
- 对于 “C” 和 “D” 操作,题目数据保证记录此操作时前面总是存在一个有效的分数
Typescript 版算法实现
1 )方案 1
function calPoints(operations: string[]): number {
// 用于存放历史数据的数组
let result:number[] = []
// 上一轮的数据
let pre1: number
// 上上轮的数据
let pre2: number
// 对数组进行遍历,遍历的目的是处理得分
operations.forEach((item: any) => {
switch (item) {
case 'C':
if (result.length) {
result.pop()
}
break
case 'D':
pre1 = result.pop()
result.push(pre1, pre1 * 2)
break
case '+':
pre1 = result.pop()
pre2 = result.pop()
result.push(pre2, pre1, pre2 + pre1)
break
default:
result.push(item * 1)
}
})
// 返回一个累加器
return result.reduce((total, num) => { return total + num }, 0)
};
- 就是按照题目要求,一步一步操作,进栈出栈
- 这个代码比较长,有些面向过程编程的感觉
2 )方案 2
function calPoints(operations: string[]): number {
// 初始化容器
const numStack: number[] = [];
// 累加器
const sum = (nums: number[]) => {
return nums.reduce((i, j) => i + j, 0);
}
// 操作对应数组
const operationMap = {
C: () => numStack.pop(),
D: () => numStack.push(numStack[numStack.length - 1] * 2),
'+': () => numStack.push(sum(numStack.slice(-2))),
}
// 遍历操作数进行匹配操作
operations.forEach(o => {
Number(o) ? numStack.push(Number(o)) : operationMap[o]()
})
return sum(numStack);
};
- 这是官方示例,这里数据结构设置的比较合适
- 使用Map结构存储操作函数,对数据进行处理
- 方案2比方案1要精简,代码质量更高
Python3 版算法实现
1 )方案 1
class Solution:
def calPoints(self, operations: List[str]) -> int:
# 用于存放历史数据的列表
result = []
# 上一轮的数据
pre1 = None
# 上上轮的数据
pre2 = None
# 对列表进行遍历,遍历的目的是处理得分
for item in operations:
if item == 'C':
if result:
result.pop()
elif item == 'D':
pre1 = result.pop()
result.append(pre1)
result.append(pre1 * 2)
elif item == '+':
pre1 = result.pop()
pre2 = result.pop()
result.append(pre2)
result.append(pre1)
result.append(pre2 + pre1)
else:
result.append(int(item))
# 返回一个累加值
return sum(result)
2 )方案 2
class Solution:
def calPoints(self, operations: List[str]) -> int:
numStack = []
def sumNums(nums):
return sum(nums)
for op in operations:
try:
num = int(op)
numStack.append(num)
except ValueError:
sLength = len(numStack)
if op == "C":
if sLength > 0:
numStack.pop()
elif op == "D":
if sLength > 0:
lastNum = numStack[sLength-1]
numStack.append(lastNum * 2)
elif op == "+":
if sLength > 1:
lastNum1 = numStack[sLength-1]
lastNum2 = numStack[sLength-2]
numStack.append(lastNum1 + lastNum2)
return sumNums(numStack)
Go 版算法实现
1 )方案 1
func calPoints(operations []string) int {
// 用于存放历史数据的切片
result := []int{}
// 上一轮的数据
var pre1 int
// 上上轮的数据
var pre2 int
// 对切片进行遍历,遍历的目的是处理得分
for _, item := range operations {
switch item {
case "C":
if len(result) > 0 {
result = result[:len(result)-1]
}
case "D":
if len(result) > 0 {
pre1, result = result[len(result)-1], result[:len(result)-1]
result = append(result, pre1, pre1*2)
}
case "+":
if len(result) > 1 {
pre1, result = result[len(result)-1], result[:len(result)-1]
pre2, result = result[len(result)-1], result[:len(result)-1]
result = append(result, pre2, pre1, pre2+pre1)
}
default:
// 将字符串转换为整数并添加到结果切片中
num, _ := strconv.Atoi(item)
result = append(result, num)
}
}
// 返回一个累加值
total := 0
for _, num := range result {
total += num
}
return total
}
2 )方案 2
func calPoints(operations []string) int {
// 初始化容器
numStack := []int{}
// 累加器
sumNums := func(nums []int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
// 操作映射
operationMap := map[string]func(){
// sLength =
"C": func() {
if len(numStack) > 0 {
numStack = numStack[:len(numStack)-1]
}
},
"D": func() {
if len(numStack) > 0 {
lastNum := numStack[len(numStack)-1]
numStack = append(numStack, lastNum*2)
}
},
"+": func() {
if len(numStack) > 1 {
lastNum1 := numStack[len(numStack)-1]
lastNum2 := numStack[len(numStack)-2]
numStack = append(numStack, lastNum1+lastNum2)
}
},
}
// 遍历操作数进行匹配操作
for _, op := range operations {
if num, err := strconv.Atoi(op); err == nil {
numStack = append(numStack, num)
} else {
if f, ok := operationMap[op]; ok {
f()
}
}
}
return sumNums(numStack)
}
575



被折叠的 条评论
为什么被折叠?



