「Leetcode-算法_MId1006」从单栈到双栈
Mid 1006 笨阶乘 栈/后缀
运算优化 + 栈
思路描述
每四个数一组
这四个数中前三个会进行乘、除 然后与最后一个相加
Stack
入前三个之和 与 最后一个数
以
4
举例运算式
4 * 3 / 2 + 1
--> (4 * 3 / 2) + 1
以 temp
代表括号内元素运算值
plus
代表括号后元素运算值
循环入队 temp
、plus
循环运算 temp
+ plus
- temp
+ plus
当 stack.size() == 1
时 返回结果
数据运算过程
测试 5
- 5 * 4 / 3 + 2 -1
- temp
- 20
- 6
- plus
- 2
- 再处理
- temp
- 1
- stack
- 6 2 1
- temp
测试 6
- 6 * 5 / 4 + 3 - 2 * 1
- temp
- 30
- 7
- plus
- 3
- 再处理
- temp
- 2
- plus
- null
- stack
- 7 3 2
- temp
代码实现
class Solution {
public int clumsy(int N) {
// 先乘除 后加减
// 标识
int temp , result = 0;
Deque<Integer> stack = new LinkedList<>();
while (N > 0) {
// 矫正 4 + 1
if (N > 1) {
temp = multiplication(N, --N);
} else {
temp = N;
}
// 作除法
if (N > 1) {
stack.offerLast(divsion(temp, --N));
} else{
stack.offerLast(temp);
break;
}
if (N > 1) {
stack.offerLast(--N);
} else{
break;
}
// 后移移位 防止 下一位出错 因为下一位可能进行乘法
--N;
}
while (stack.size() > 1) {
stackPlus(1, stack);
if (stack.size() > 1) {
stackPlus(-1, stack);
}
}
return stack.pollFirst();
}
private int multiplication(int a, int b) {
return a * b;
}
private int divsion(int a, int b) {
return Math.floorDiv(a, b);
}
private void stackPlus(int sign, Deque<Integer> stack) {
stack.offerFirst(stack.pollFirst() + stack.pollFirst() * sign);
}
}
算法分析
时间复杂度: O(n)
空间复杂度: O(1)
通用计算器
维护双栈
知识栈:
后缀表达式(逆波兰式)
Deque 双端队列接口
法 作用 ll/add 添加元素 fer/remove 删除元素 ek/get 读取元素 支持
语法
+ First/Last 对头、尾 实现双向操作
记录在这里的一处踩坑:
- calculate() 中 一开始为了减少局部变量的使用 直接用deq.pollLast() 导致减法、除法运算时逻辑上的错误
class Solution {
// 计算器
public int clumsy(int N) {
Deque<Integer> numDeq = new LinkedList();
Deque<Character> operatorDeq = new LinkedList();
// 操作符优先级
Map<Character,Integer> priorityMap = new HashMap<>(){
{
put('*',2);
put('/',2);
put('-',1);
put('+',1);
}
};
char[] operators = new char[]{'*','/','+','-'};
for (int i = N, index = 0; i > 0 ; --i, ++index) {
// 数字直接入栈
numDeq.offerLast(i);
// 取对应操作符
char operator = operators[index % 4];
// 操作符栈不为空 且 栈内元素优先级都 高于 当前将入栈的操作符 ——》 计算栈内所有可以计算的
while (!operatorDeq.isEmpty() && priorityMap.get(operatorDeq.peekLast()) >= priorityMap.get(operator)) {
calculate(numDeq, operatorDeq);
}
// 操作符入栈
operatorDeq.offerLast(operator);
}
// 由于最后一个操作符没必要入栈 所以 取出
operatorDeq.pollLast();
while (!operatorDeq.isEmpty()) {
calculate(numDeq, operatorDeq);
}
return numDeq.peekLast();
}
// 计算函数-->取出 N 栈底两个元素 与 O 栈一个元素去运算;
private void calculate(Deque<Integer> numDeq, Deque<Character> operatorDeq) {
// 这里一定要把 两个都取出来 不然不能算减法和除法
int addtion = 0 , a = numDeq.pollLast() , b = numDeq.pollLast();
switch (operatorDeq.pollLast()){
case '+' : addtion = a + b;break;
case '-' : addtion = b - a;break;
case '*' : addtion = a * b;break;
case '/' : addtion = Math.floorDiv(b , a);break;
}
numDeq.offerLast(addtion);
}
}
双栈的图示
N=3 index=2
N = 3 index = 3
鸣谢:三叶姐姐的题解 双栈计算器是和这篇题解学的
战报
因为这道题的标签是
数学
(找规律) , 排名不必过多在意
「Leetcode-算法_MId1006」从单栈到双栈的更多相关文章
- 算法总结之 在单链表和双链表中删除倒数第k个节点
分别实现两个函数,一个可以删除单链表中倒数第k个节点,另一个可以删除双链表中倒数第k个节点 思路: 如果链表为空,或者k<1 参数无效 除此之外 让链表从头开始走到尾,每移动一步,就让k的值减1 ...
- 双栈(Dual Stack)
参考博客: 双栈数据结构: https://blog.csdn.net/hebtu666/article/details/83011115 https://blog.csdn.net/cainv89/ ...
- LeetCode 1248. 统计「优美子数组」
地址 https://www.acwing.com/solution/leetcode/content/5801/ 题目描述给你一个整数数组 nums 和一个整数 k. 如果某个子数组中恰好有 k 个 ...
- 字符串匹配「 KMP 算法 」
引言 众所周知,字符串无论是在 OI 中还是别的计算机领域都占有比较大的比重,今天说的就是一个关于匹配字符串的算法——「 KMP 算法 」. 0x00 KMP 算法用于解决这样的一类问题:给定一个文本 ...
- leetcode算法学习----155. 最小栈(MinStack )
下面题目是LeetCode算法155题: https://leetcode.com/problems/min-stack/ 题目1:最小函数min()栈 设计一个支持 push,pop,top 操作, ...
- ACM金牌选手讲解LeetCode算法《栈和队列的高级应用》
大家好,我是编程熊,双非逆袭选手,字节跳动.旷视科技前员工,ACM金牌,保研985,<ACM金牌选手讲解LeetCode算法系列>作者. 上一篇文章讲解了<线性表>中的数组.链 ...
- 图解最长回文子串「Manacher 算法」,基础思路感性上的解析
问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...
- 「算法笔记」快速数论变换(NTT)
一.简介 前置知识:多项式乘法与 FFT. FFT 涉及大量 double 类型数据操作和 \(\sin,\cos\) 运算,会产生误差.快速数论变换(Number Theoretic Transfo ...
- 力扣Leetcode 1248. 统计「优美子数组」
统计「优美子数组」 给你一个整数数组 nums 和一个整数 k. 如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」. 请返回这个数组中「优美子数组」的数目. 示例 ...
随机推荐
- modal 弹框遮罩层,滚动穿透bug 解决方案
modal 弹框遮罩层,滚动穿透bug 解决方案 parent component 动态设置 lock css const computedClassName = classNames( 'activ ...
- NDB程序进近复飞保护区的绘制
终于有点空闲,找张图来演练一下<风螺旋标准模板>软件的用法. 某机场NDB进近程序剖面图如下图所示: 该机场采用了近台和远台的双台布局,近台和远台均为NDB与指点标的合装台,没有中间进近定 ...
- C++算法代码——你要乘坐的飞碟在这里[usaco]
题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?id=1056 题目描述 一个众所周知的事实,在每一慧星后面是一个不明飞行物UFO. 这些不明 ...
- ElasticSearch DSL 查询
公号:码农充电站pro 主页:https://codeshellme.github.io DSL(Domain Specific Language)查询也叫做 Request Body 查询,它比 U ...
- Dokcer中Mysql的数据导入导出
导出 1.首先进入容器,输入提取数据库文件命令 mysqldump -u root -p rw 数据库名> 输出.sql,提取到当前容器 2.退出容器,进入linux:输入拷贝命令 docker ...
- 将项目加载到tomcat中的时候报错:Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules
转自:http://jingwang0523.blog.163.com/blog/static/9090710320113294551497/ 最近在用eclipse做项目,新建项目时什么都贪新,用最 ...
- Django自学计划之集装箱货物运输物流仓储一站式ERP系统
业余开始学习时间:2018年1月 业余学习时间段:每天下班晚饭后时间+无事的星期六和星期天+上班时的空闲时间 自学目标: 1.我们要用管理的思维来写我们的系统! 2.我们要用我们的ERP系统帮助中小集 ...
- Jquery获取链接请求的参数
比如有一个链接:https://www.baidu.com/s?cl=3&tn=baidutop10&fr=top1000,先定义方法: //获取url中的参数 function ge ...
- 查看浏览器 请求网页 中 header body cookie
command + alt + i 进入开发者工具 重新刷新页面进行请求URL 进入Network 选中某个url 右侧会展示详细信息
- Android7.0无需FileProvide搞定URI拍照、应用安装问题
根据官方文档,从Android7.0版本开始 使用URI打开或安装文件需要单独在应用里配置了,问了度娘,有好多版本的结果,个人认为最靠谱的就是下边这个方法,只需在application的oncreat ...