leetcode_2 Evaluate Reverse Polish Notation 逆波兰表达式

逆波兰表达式计算四则运算。请看题目要求:

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +-*/. Each operand may be an integer or another expression.

Some examples:

  ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9
  ["4", "13", "5", "/", "+"] -> (4 + (13 / 5)) -> 6

然后想起了本科学的数据结构中有一部分讲到了这个逆波兰表达式,用比波兰表达式来计算的算法是典型的栈问题。将数字压入栈,遇到计算符的时候弹出运算数,进行运算,结果再压入栈。最后栈中的数据就是结果。先看答案,然后再对比之前学过的进行分析。


#include <iostream>
#include <vector>
#include <stack>
#include <string>
using namespace std;
class Solution {
public:
	bool isOpeartor(string value){
// 		if(value == "+"||value == "-"||value == "*"||value == "/")
// 			return false;
// 		else
// 			return true;
        bool val =true;
		(value == "+")?(val=false):( (value == "-")?(val=false):((value == "*")?(val=false):( (value == "/")?(val=false):(val=true) )));
		return val;
		
	}
	int calValue(int operator1,int operator2,string operators){
		if(operators=="+")
			return (operator1+operator2);
		else if(operators=="-")
			return (operator1-operator2);
		else if(operators=="*")
			return (operator1*operator2);
		else 
			return (operator1/operator2);
	}
    int evalRPN(vector<string> &tokens) {
        stack<int> str_stack;
		vector<string>::iterator iter = tokens.begin();
		while(iter != tokens.end()){
			if(isOpeartor( (*iter))){
				//true的话为数字
				int tmp = atoi((*iter).c_str());
				str_stack.push(tmp);

			}
			else{
				int num2 =  str_stack.top();
				str_stack.pop();
				int num1 =  str_stack.top();
				str_stack.pop();
				str_stack.push(calValue(num1,num2,(*iter)));

			}
			iter++;
		}
		return str_stack.top();

    }
};

第一遍的代码使用的是不是上述代码,区别在于isOpeartor方法使用的是注释部分,其运算的时间是:


基于第一题的解题习惯之后,惯性的就想了想有没有更优化更快速的方法,于是想着对代码进行优化。在仔细看了代码之后,发现最好优化的地方就是isOpeartor方法,于是将if else表达式换成?:这个三元运算符,运算的速度还是快于代码判断,结果时间果然快了近20ms:



暂时还没想到更好的地方优化,如果大家看到这篇博客,欢迎提出好的优化方法。



接下来分析这个问题与原来课本中的例子:

这个问题简化地方在于:拿到一个运算表达式不需要转化成逆波兰表达式,转化的过程其实难于这个运算过程,这个就简化了很多。第二个简化是这里没有更多其他的运算符,如一元运算符++等,如果包含了这些运算符就需要考虑运算符的优先级了。第三个简化是这里是通过vector存的表达式,如果改成string来存放表达式,这样的话难度就有提高了,需要自己去分析表达式。第三个简化是这里不支持浮点数计算。



任重道远啊。感觉还是太菜了,继续努力吧







题目描述: 给定一个字符串,请将字符串里的字符按照出现的频率降序排列。 示例 1: 输入: "tree" 输出: "eert" 解释: 'e'出现两次,'r'和't'都只出现一次。因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。 示例 2: 输入: "cccaaa" 输出: "cccaaa" 解释: 'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。注意"cacaca"是不正确的,因为相同的字母必须放在一起。 示例 3: 输入: "Aabb" 输出: "bbAa" 解释: 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。注意'A'和'a'被认为是两种不同的字符。 Java代码如下: ``` import java.util.*; public class Solution { public String frequencySort(String s) { if (s == null || s.length() == 0) { return ""; } Map<Character, Integer> map = new HashMap<>(); for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); map.put(c, map.getOrDefault(c, 0) + 1); } List<Map.Entry<Character, Integer>> list = new ArrayList<>(map.entrySet()); Collections.sort(list, (o1, o2) -> o2.getValue() - o1.getValue()); StringBuilder sb = new StringBuilder(); for (Map.Entry<Character, Integer> entry : list) { char c = entry.getKey(); int count = entry.getValue(); for (int i = 0; i < count; i++) { sb.append(c); } } return sb.toString(); } } ``` 解题思路: 首先遍历字符串,使用HashMap记录每个字符出现的次数。然后将HashMap转换为List,并按照出现次数从大到小进行排序。最后遍历排序后的List,将每个字符按照出现次数依次添加到StringBuilder中,并返回StringBuilder的字符串形式。 时间复杂度:O(nlogn),其中n为字符串s的长度。遍历字符串的时间复杂度为O(n),HashMap和List的操作时间复杂度均为O(n),排序时间复杂度为O(nlogn),StringBuilder操作时间复杂度为O(n)。因此总时间复杂度为O(nlogn)。 空间复杂度:O(n),其中n为字符串s的长度。HashMap和List的空间复杂度均为O(n),StringBuilder的空间复杂度也为O(n)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值