首页 > 编程语言 >分治算法——241. 为运算表达式设计优先级

分治算法——241. 为运算表达式设计优先级

时间:2023-08-13 14:45:14浏览次数:36  
标签:10 优先级 算式 res 分治 break vector 241 expression

分治思路:
对于一个算式来说,总是可以根据运算符分为左右两部分算式,接着分别计算结果并合并;
每一个结果都是一个数组,包含这个算式的所有可能结果,计算时将左右两部分排列组合;
递归的终点是字符串是纯数字(即分到一个算式中只剩下一个数字),直接返回。

 

比如示例中的2*3-4*5,有下面的分法:

1、分为2与3-4*5,对于3-4*5,继续细分

  •   3-4*5可以分为3与4*5,或者3-4与5,所以结果为{-17,-5}
  •   则这种分法产生的最终结果就是{-34,-10}  (2*-17=-34,  2*-5=-10)

2、分为2*3与4*5,这种分法产生的结果就是{-14}
3、分为2*3-4与5,对于2-3*4,继续细分

  • 2*3-4可以分为2与3-4,或者2*3与4,所以结果为{-2,2}
  • 则这种分法产生的最终结果就是{-10,10}

最终结果是它们的结合,也就是{-34,-10,-14,-10,10},本题是不需要我们去重的。
不论是多复杂的算式,总是可以不断分而治之,递归得到各个部分的解。

class Solution {
public:
    vector<int> diffWaysToCompute(string expression) {
        vector<int> res;
        for (int i = 0; i < expression.size(); i++){
            char c = expression[i];
            if (c == '+' || c == '-' || c == '*') {
                vector<int> left = diffWaysToCompute(expression.substr(0, i));
                vector<int> right = diffWaysToCompute(expression.substr(i+1));
                for (int m : left) {
                    for (int n : right) {
                        switch(c){
                        case '+': 
                            res.push_back(m + n);
                            break;  // 注意!一定要加break
                        case '-': 
                            res.push_back(m - n);
                            break;
                        case '*': 
                            res.push_back(m * n);
                            break;
                        }
                    }
                }
            }
        }

        if (res.empty()) {  // 递归出口:表达式中没有运算符,即只有一个纯数字
            res.push_back(std::stoi(expression));  
        }

        return res;
    }
};

 

改进:记忆化搜索

由于数据量比较小,这道题不用记搜也能过,大概在4ms左右,用了记搜能提升到0ms
还是考虑上面的例子,在第一种分法里,我们已经计算过了4*5,但是在第二种分法里,我们又算了一遍 为了减少重复计算,用哈希表作备忘录,保存算式到结果的映射,每次计算时查表/存表

 

改进:动态规划

或者与其我们从上到下用分治处理+memoization,不如直接从下到上用动态规划处理。

 

 

 

 

 


参考:https://leetcode.cn/problems/different-ways-to-add-parentheses/solutions/1636227/fen-zhi-ji-sou-by-heren1229-hp0o/

标签:10,优先级,算式,res,分治,break,vector,241,expression
From: https://www.cnblogs.com/spacerunnerZ/p/17625635.html

相关文章

  • nginx中location的写法有哪些?优先级是什么呢?rewrite如何使用?
    主要内容:一、location匹配的规则和优先级(重点,面试会问,工作用得到)二、nginx常用的问题(要求掌握)三、rewrite:重定向功能(有掌握,有理解),重定向的标识位,标识位的四种类型是重点在工作中配置nginx,主要配置locationlocation匹配:用正则表达式URI:统一资源标识符,是一种字符串标识,用于标识......
  • 与点对有关的CDQ分治(菜鸟笔记)
    参考文章   首先要说明的是CDQ是一种思想,并且扩展范围很广。   这里主要说的是与点对有关的CDQ。参考文章说了与CDQ主要解决的三大类问题。第一类就是解决和点对有关的问题。主要是给定一个长度为n的序列,然后找出其中满足题意的点对\((i,j)\)。   CDQ的......
  • 分治算法C++
    1、光荣的梦想题目描述】Prince对他在这片陆上维护的秩序感到满意,于是决定启程离开艾泽拉斯。在他动身之前,Prince决定赋予King_Bette最强大的能量以守护世界、保卫这里的平衡与和谐。在那个时代,平衡是个梦想。因为有很多奇异的物种拥有各种不稳定的能量,平衡瞬间即被打破。KB决定求......
  • 浅谈根号分治
    浅谈根号分治一、问题引入  给定一个长度为\(n\)的序列,进行\(m\)次询问。每次询问给出两个数字\(x,y\)。对于每次询问,输出所有下标模除\(x\)等于\(y\)的元素的总和。  对于这个问题,我们发现他要维护的是一段离散的元素的和,而我们平时学的数据结构,如线段树等都只能维护一段......
  • 【Linux】进程优先级 | 进程的切换 | 环境变量详解
      ......
  • 【学习笔记】线段树分治
    定义线段树分治是一种解决一类有插入、删除和整体查询操作的问题的方法。它是一种离线做法,通过在线段树上记录操作的时间区间来处理修改对询问的影响。每个操作被看作一个时间区间的修改,并在线段树上进行标记。然后通过深度优先搜索(DFS)依次执行这些操作,直到根节点来回答查询,并在......
  • 根号分治-2023牛客7 E-Star Wars
      也就是说对于大点和小点我们采用不同的方式维护对于大点来说我们只需要记录它的周围点的总和不需要知道具体的谁链接了它 对于小点我们需要维护它的所有信息他自己链接了哪些点 需要再开一个vector表示自己链接的大点这样大对大或者小对大的时候维护的信息也......
  • linux应用进程优先级配置
    linux应用进程优先级配置example:#include<sched.h>intset_process_priority(void){ intpri; structsched_paramparam; pri=sched_get_priority_min(SCHED_RR); if(pri==-1){ printf("sched_get_priority_max()failed\n"); return-1; }......
  • 国产化SCT52241双通道下管IGBT/MOSFET栅极驱动器,可替代UCC27525A、ISL89165等
    SCT52241是是一款宽供电电压、双通道、高速、低测栅极驱动器,包括功率MOSFET,IGBT。单个通道能够提供高达4A拉电流和4A灌电流的轨到轨驱动能力,并实现轨到轨输出。高达24V宽电压范围提高功率器件开关瞬间栅极驱动的振铃幅值裕度。13ns输入输出传输延迟特性适合高频功率转换器应用。SCT......
  • 【W的AC企划 - 第六期】树上分治
    往期浏览树上分治点分治讲解每次选取树的重心进行递归分治,中阶算法,大部分模板不需要理解,但是每一题都需要对维护函数进行修改。复杂度\(\mathcalO(N\logN)\)。个人封装由于需要进行一定程度的修改,不符合结构体封装的原则,故没有使用结构体。introot=0,MaxTree=1e1......