题目
给你一个由数字和运算符组成的字符串 expression ,按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。你可以 按任意顺序 返回答案。
生成的测试用例满足其对应输出值符合 32 位整数范围,不同结果的数量不超过 104 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/different-ways-to-add-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例
思路
题目要求按不同优先级组合数字和运算符,计算并返回所有可能组合的结果。
对于一个形如 x op y(op 为运算符,x 和 y 为数) 的算式而言,它的结果组合取决于 x 和 y 的结果组合数,而 x 和 y 又可以写成形如 x op y 的算式。
因此,该问题的子问题就是 x op y 中的 x 和 y:以运算符分隔的左右两侧算式解。
然后我们来进行 分治算法三步走:
分解:按运算符分成左右两部分,分别求解
解决:实现一个递归函数,输入算式,返回算式解
合并:根据运算符合并左右两部分的解,得出最终解
每一个问题都可以分为两个子问题,而每个子问题又可以分为两个子问题,并且问题与子问题之间的求解思路都是一样的
代码
int* diffWaysToCompute(char * input, int* returnSize){
if(input == NULL){
*returnSize = 0;
return NULL;
}
int len = strlen(input);
char *lstr = (char *)calloc(len, sizeof(char));
char *rstr = (char *)calloc(len, sizeof(char));
int mid = 0;
int retcnt = 0;
int calflag = 0;
int *ret = (int *)calloc(1, sizeof(int));
while(mid < len){
if(input[mid] >= '0' && input[mid] <= '9'){
mid++;
continue;
}
calflag = 1;
memcpy(lstr, input, mid);
lstr[mid] = '\0';
memcpy(rstr, input+mid+1, len-mid-1);
rstr[len-mid-1] = '\0';
int lsize = 0;
int rsize = 0;
int *lret = diffWaysToCompute(lstr, &lsize);
int *rret = diffWaysToCompute(rstr, &rsize);
int *retmp = (int *)realloc(ret, (retcnt+lsize*rsize)*sizeof(int));
if(retmp == NULL){
return NULL;
}
ret = retmp;
for(int i = 0; i < lsize; i++){
for(int j = 0; j < rsize; j++){
switch(input[mid]){
case '+':
ret[retcnt++] = lret[i]+rret[j];
break;
case '-':
ret[retcnt++] = lret[i]-rret[j];
break;
case '*':
ret[retcnt++] = lret[i]*rret[j];
break;
default:
break;
}
}
}
mid++;
}
if(calflag == 0){
*returnSize = 1;
ret[0] = atoi(input);
return ret;
}
*returnSize = retcnt;
return ret;
}
时间空间复杂度