(关注数据结构和算法,了解更多新知识)
一网友说公司为了逼他离职,故意把他的工位安排到厕所旁,该网友直接记录领导如厕时间,然后发到公司群。
只能说该公司真的是恶心,想开除直接开就行了,只要赔偿到位,没人会赖着不走。使用这种手段无非就是不想给赔偿逼迫员工自己离职,我们再来看下各位网友的评论。
--------------下面是今天的算法题--------------
来看下今天的算法题,这题是LeetCode的第241题:为运算表达式设计优先级。
问题描述
来源:LeetCode第241题
难度:中等
给你一个由数字和运算符组成的字符串 expression ,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以按任意顺序返回答案。
生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 10^4 。
示例1:
输入:expression = "2-1-1"
输出:[0,2]
解释:
((2-1)-1) = 0
(2-(1-1)) = 2
示例2:
输入:expression = "2*3-4*5"
输出:[-34,-14,-10,-10,10]
解释:
(2*(3-(4*5))) = -34
((2*3)-(4*5)) = -14
((2*(3-4))*5) = -10
(2*((3-4)*5)) = -10
(((2*3)-4)*5) = 10
1 <= expression.length <= 20
expression 由数字和算符 '+'、'-' 和 '*' 组成。
输入表达式中的所有整数值在范围 [0, 99]
问题分析
这题是用一个由数字和运算符组成的字符串,按照不同的组合划分计算对应的值。
这是一道典型的分治算法题,把字符串分为两部分,分别计算每部分的结果,然后这两部分在进行合并。每部分的计算实际上又是原问题的一个子问题,就这样一直递归下去,当子串只包含数字的时候就不在继续递归。
JAVA:
// 分治思想
public List<Integer> diffWaysToCompute(String expression) {
return dfs(expression, 0, expression.length());
}
// 左闭右开区间
private List<Integer> dfs(String expression, int start, int end) {
List<Integer> ans = new ArrayList<>();
for (int i = start; i < end; i++) {
char ch = expression.charAt(i);
if (ch == '-' || ch == '+' || ch == '*') {
// 字符串分割两半,前部分计算的可能结果
List<Integer> left = dfs(expression, start, i);
// 后部分计算的可能结果
List<Integer> right = dfs(expression, i + 1, end);
for (int x : left) {
for (int y : right) {
if (ch == '-') {
ans.add(x - y);
} else if (ch == '+') {
ans.add(x + y);
} else if (ch == '*') {
ans.add(x * y);
}
}
}
}
}
// 如果是纯数字就添加到集合中
if (ans.isEmpty())
ans.add(Integer.parseInt(expression.substring(start, end)));
return ans;
}
C++:
public:
vector<int> diffWaysToCompute(string expression) {
return dfs(expression, 0, expression.size());
}
// 左闭右开区间
vector<int> dfs(string expression, int start, int end) {
vector<int> ans;
for (int i = start; i < end; i++) {
char ch = expression[i];
if (ch == '-' || ch == '+' || ch == '*') {
// 字符串分割两半,前部分计算的可能结果
vector<int> left = dfs(expression, start, i);
// 后部分计算的可能结果
vector<int> right = dfs(expression, i + 1, end);
for (int x: left) {
for (int y: right) {
if (ch == '-') {
ans.push_back(x - y);
} else if (ch == '+') {
ans.push_back(x + y);
} else if (ch == '*') {
ans.push_back(x * y);
}
}
}
}
}
// 如果是纯数字就添加到集合中
if (ans.empty())
ans.push_back(stoi(expression.substr(start, end)));
return ans;
}
C:
// 左闭右开区间
int *dfs(char *expression, int start, int end, int len, int *count, int *returnSize) {
int *ans = malloc(2000 * sizeof(int));
for (int i = start; i < end; i++) {
char ch = expression[i];
if (ch == '-' || ch == '+' || ch == '*') {
// 字符串分割两半,前部分计算的可能结果
int *leftCount = calloc(1, sizeof(int));
int *left = dfs(expression, start, i, len, leftCount, returnSize);
// 后部分计算的可能结果
int *rightCount = calloc(1, sizeof(int));
int *right = dfs(expression, i + 1, end, len, rightCount, returnSize);
for (int j = 0; j < *leftCount; ++j) {
for (int k = 0; k < *rightCount; ++k) {
if (ch == '-') {
ans[(*count)++] = left[j] - right[k];
} else if (ch == '+') {
ans[(*count)++] = left[j] + right[k];
} else if (ch == '*') {
ans[(*count)++] = left[j] * right[k];
}
}
}
}
}
// 如果是纯数字就添加到集合中
if (*count == 0) {
int num = 0;
for (int i = start; i < end; ++i)
num = num * 10 + expression[i] - '0';
ans[(*count)++] = num;
}
if (start == 0 && end == len)
*returnSize = *count;
return ans;
}
int *diffWaysToCompute(char *expression, int *returnSize) {
*returnSize = 0;
int count = 0, len = (int) strlen(expression);
return dfs(expression, 0, len, len, &count, returnSize);
}
Python:
def diffWaysToCompute(self, expression: str) -> List[int]:
# 左闭右开区间
def dfs(start: int, end: int):
ans = []
for i in range(start, end):
ch = expression[i]
if ch == '-' or ch == '+' or ch == '*':
# 字符串分割两半,前部分计算的可能结果
left = dfs(start, i)
# 后部分计算的可能结果
right = dfs(i + 1, end)
for x in left:
for y in right:
if ch == '-':
ans.append(x - y)
elif ch == '+':
ans.append(x + y)
elif ch == '*':
ans.append(x * y)
# 如果是纯数字就添加到集合中
if not ans:
ans.append(int(expression[start: end]))
return ans
return dfs(0, len(expression))
笔者简介
博哥,真名:王一博,毕业十多年,《算法秘籍》作者,专注于数据结构和算法的讲解,在全球30多个算法网站中累计做题2000多道,在公众号中写算法题解800多题,对算法题有自己独特的解题思路和解题技巧,喜欢的可以给个关注,也可以下载我整理的1000多页的PDF算法文档。