「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 个奇数数字,我们就认为这个子数组是「优美子数组」. 请返回这个数组中「优美子数组」的数目. 示例 ...
随机推荐
- js 运算符的执行顺序
js 运算符的执行顺序 js 运算符优先级 Operator Precedence 下表从最高(21)到最低(1)优先顺序排列 left-to-right 从左到右 / 先左后右 right-to-l ...
- window.ShadyCSS
window.ShadyCSS Web Components # install $ yarn add @webcomponents/shadycss@1.7.1 # OR $ npm i @webc ...
- how to write an ebook that can support published by format PDF, Epub, Mobi and so on
how to write an ebook that can support published by format PDF, Epub, Mobi and so on 如何写一本自己的电子书,支持各 ...
- windows10 安装NASM
NASM官网 下载NASM NASM在线HTML文档 下载golink golink文档 NASM教程 in windows x64调用约定 x86调用约定 编码样式约定 在编写nasm时数字默认为1 ...
- 【转】奇异值分解(SVD)原理详解及推导
原文地址:https://blog.csdn.net/zhongkejingwang/article/details/43053513,转载主要方便随时查阅,如有版权要求,请及时联系. 在网上看到有很 ...
- 26_ mysql数据操作语言:DELETE语句
-- DELETE语句 -- 删除10部门中,工龄超过20年的员工记录 DELETE FROM t_emp WHERE deptno=10 AND DATEDIFF(NOW(),hiredate)/3 ...
- Java 动态调试技术原理及实践
本文转载自Java 动态调试技术原理及实践 导语 断点调试是我们最常使用的调试手段,它可以获取到方法执行过程中的变量信息,并可以观察到方法的执行路径.但断点调试会在断点位置停顿,使得整个应用停止响应. ...
- C++ Primer Plus 第一章 预备知识
C++ Primer Plus 第一章 预备知识 知识点梳理 本章主要讲述了C++的由来,讨论了面向过程语言与面向对象语言的区别,介绍了ANSI/ISO制定的C++标准,阐述了在Windows.Mac ...
- 开发在线教育平台项目步骤(Python3.7.6 + Django 3.0)
1. 新建虚拟环境 mkvirtualenv eduonline 2. 安装mysql数据库 pip install mysqlclient pip install pymysql 3. 在setti ...
- 2020年12月-第02阶段-前端基础-CSS Day02
CSS Day02 复合选择器 后代选择器 并集选择器 1. CSS复合选择器 理解 理解css复合选择器分别的应用场景 为什么要学习css复合选择器 CSS选择器分为 基础选择器 和 复合选择器 , ...