stack专题

20 Valid Parentheses

问题:没有意识到字符串中只包含字符:’(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’
代码:git代码

682 Baseball Game

问题:错误在+操作:top1 先弹出,top2 再弹出,还原到stack里面的时候,要先放top2,再放top1,最后放score = top1+top2;从优秀代码中学习到的优点:谁说栈就只能用stack了?linkedList也可以;每种操作都优先考虑放入栈中,再考虑加入到sum中。这是我没有注意的,我的思考顺序就很随便了。

public int calPointsV2(String[] ops) {int sum = 0;LinkedList<Integer> list = new LinkedList<>();for (String op : ops) {if (op.equals("C")) {sum -= list.removeLast();}else if (op.equals("D")) {list.add(list.peekLast() * 2);sum += list.peekLast();}else if (op.equals("+")) {list.add(list.peekLast() + list.get(list.size() - 2));sum += list.peekLast();}else {list.add(Integer.parseInt(op));sum += list.peekLast();}}
        return sum;}

代码:git代码

496 Next Greater Element I

问题:这道题目,自己首先是理解题意有问题。对于nums1中的每个元素,先查找num2中自己(这个元素)所在位置,从右侧开始查找,最近的一个比当前元素大的元素。我理解成对应的下标了。从优先代码学习到观察之后能发现在一个递减序列中,遇到一个大的元素,那这个元素就是这个序列中每个元素的下一个更大元素。
代码:git代码

735 Asteroid Collision

问题:我的问题是在写代码的时候没有把if 情况合并起来,写出来的代码不够简洁。
代码:git代码

103 Binary Tree Zigzag Level Order Traversal

问题:遍历节点和添加值到结果中这两个步骤要分清楚
代码:git代码

144 Binary Tree Preorder Traversal

问题:if条件的位置影响程序的执行时间
代码:git代码

402 Remove K Digits

问题:这道题目最后卡在了超时问题上。参考了最佳答案。原始思路是:每次删除一位数字,得到新的最小num,再删除,直到删除k个数字。需要求每次删除一位数字,如果得到最小的num:从高位开始删除,遇到比当前最小值大的删除操作就停止。例如1432219删除第一位的步骤是:删除1,得到:432219;删除4,得到:132219;删除3,得到142219。因为142219>132219,所以停止本次循环。接着使用132219,再删除一位,步骤是:删除1,得到32219;删除3,得到12219,;删除2得到:13219;13219 > 12219 ,所以停止本次循环。依次处理k次。时间复杂度是O(nk)。
参考代码:看了discussion,思路是这样的。往栈里面push元素。如果当前元素比栈顶元素小,则pop。每一次pop,k需要减1;一直到当前元素大于栈中的元素。前提条件是k>0。

public String removeKdigitsV3(String num, int k) {int digits = num.length() - k;// 最后会留下digits长度的字符char[] stk = new char[num.length()];int top = 0;// 栈的顶端for (int i = 0; i < num.length(); i++) {char c = num.charAt(i);while (top > 0 && stk[top - 1] > c && k > 0) {top -= 1;k -= 1;}stk[top++] = c;}int idx = 0;while (idx < digits && stk[idx] == '0')idx++;return idx == digits ? "0" : new String(stk, idx, digits - idx);}

代码:代码位置

394 Decode String

问题:看了题目之后首先想到先计算内层的[],再计算外层的[]。始终用一个变量来记录最后的结果。分析遇到数字应该做什么,遇到[、]、字母分别应该做什么,就能得到代码。即使思路想明白了,在代码实现上一点小的区别和改动,就能得到流畅的代码和不优雅的代码。看decodeStringV2和decodeStringV3的区别
代码

385 Mini Parser

问题:本题和上一题类似,也有嵌套。区别是本题有效的全是数字。我学习到的是递归思路。上题分析了,找到遇到不同类型的字符时候怎么处理。还有一种是递归。对于:[123,[456,[789]]] ,我们可以先处理123,[456,[789]],进而可以处理:123 和 [456,[789]];对于123,直接处理转为int;对于[456,[789]],我们可以先处理456,[789];进而分别处理456和[789]。对于[789],我们处理789。不断递归,不断缩小问题。
递归思想:先处理退出情况。处理不断递归对结果的影响。

public NestedInteger deserializeV3(String s) {if (s.length() == 0)return new NestedInteger();if (s.charAt(0) != '[')return new NestedInteger(Integer.parseInt(s));if (s.length() <= 2)return new NestedInteger();NestedInteger res = new NestedInteger();int start = 1, cnt = 0;for (int i = 1; i < s.length(); ++i) {if (cnt == 0 && (s.charAt(i) == ',' || i == s.length() - 1)) {res.add(deserializeV3(s.substring(start, i)));start = i + 1;} else if (s.charAt(i) == '[')++cnt;else if (s.charAt(i) == ']')--cnt;}return res; }

341. Flatten Nested List Iterator

问题:把嵌套的int展开。这里也是一个递归思想。
代码

331 Verify Preorder Serialization of a Binary Tree

问题:题目中说明给定的字符串是一个二叉树先序遍历的结果。判断是不是一颗有效的二叉树。这里注意两点:1 树的叶子节点一定是空节点;2 可能会有多余的节点。
我的思路:第一感觉是用stack。我按着操作顺序走一遍,觉得自己应该能写出代码;发现写不出来;后来我就分开访问节点与判断节点是否有效,写出了第一版的代码。写完后发现,因为是一颗二叉树,所以最终就是判断preorder[0]是不是一个有效节点就可以了。所以合并了访问节点与判断节点是否有效的操作。写出来第一版的递归代码。不满意的地方是index使用了全局变量,处理得不好。
别人的代码:所有的叶子节点是空节点,说明这颗二叉树是一颗满树。二叉树满树有一个特性:叶子节点数量=非叶子节点数量+1。利用二叉树的性质。聪明。当然还有些解决方法用了入度、出度的概念,我就没有继续学习了。思维扩散开来就好了。
代码

456 132 Pattern

问题:输入int数组,判断数组是否包含下标:i<j<k,数值a[i]<a[k]<a[j]这样格式的组合。这道题目按照直觉三层循环解决非常简单,但是会遇到超时的问题。
学习:思路一:固定j;当 i确定了之后,nums[k]就一定在 (nums[i],nums[j])之间。既然nums[j]已经确定了,那就应该找一个尽可能小的nums[i]在[0,j)之间。
学习:思路二:使用了栈,参考了别人的文章。a[i]<a[k]<a[j],a[j]是最大值,用栈存这个值。还需要找到一个尽可能大的a[k],但是又<a[j],记为third。因为k>j,所以从数组的末尾开始遍历。当a[k]和a[j]确定之后,只要判断a[i]<third就返回true。至于如何能想到这么解决,我想应该是题目做多了,自然就有感觉了吧。
代码

/*** i<j<k* a[i]<a[k]<a[j]* @param nums* @return*/public boolean find132patternV3(int[] nums) {int third = Integer.MIN_VALUE;//a[k]Stack<Integer> stack = new Stack<Integer>();for(int i=nums.length - 1;i>=0;i--){//nums[i] = a[i]if(nums[i] < third){return true;}else{while(!stack.isEmpty() && nums[i] > stack.peek()){third = stack.pop();}stack.push(nums[i]);//a[j]}}return false;}

739 Daily Temperatures

问题:输入: [73, 74, 75, 71, 69, 72, 76, 73],输出[1, 1, 4, 2, 1, 1, 0, 0]。直观的解决方法很简单。两层循环,当i确认的时候,j比i大,找到第一个nums[i]<nums[j]的j,r[i] = j-i。时间复杂度是n2
学习:使用栈,几乎是O(n)的复杂度。自己也想过放栈里面,但是想着想着就不知道怎么做了,看着别人这么做,觉得好简单。遇到下标i,放入栈中,接着向后遍历(因为符合条件的元素肯定在后面)。当遇到nums[i]>nums[]的情况下,就是找到答案了。当然可能多个元素,符合条件的下标都是i,所以需要循环栈。需要处理的元素放入栈,每遍历一个元素,看这个元素是否符合栈内元素的要求。和456题有点类似。

public int[] dailyTemperaturesV2(int[] temperatures) {int[] result = new int[temperatures.length];Stack<Integer> stack = new Stack<Integer>();for(int i=0;i<temperatures.length;i++){while(!stack.isEmpty() && temperatures[i] > temperatures[stack.peek()]){int idx = stack.pop();result[idx] = i - idx;}stack.push(i);}return result;}

503 Next Greater Element II

问题:这是一个可循环的数组,找到每个元素下标最接近的下一个比较大的元素。这依然是一道找到较大值的题目。和上一个题目类似,用stack类解决。我的思路是先找一遍,再找一遍。循环两次,因为毕竟是个循环数组。

public int[] nextGreaterElements(int[] nums) {int[] result = new int[nums.length];Stack<Integer> stack = new Stack<Integer>();for (int i = 0; i < nums.length; i++) {result[i] = -1;while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) {result[stack.pop()] = nums[i];}stack.push(i);}for (int i = 0; i < nums.length - 1; i++) {while (!stack.isEmpty() && nums[i] > nums[stack.peek()]) {result[stack.pop()] = nums[i];}}return result;}

学习:有人总结了循环数组问题的解决思路。方法一:将原始数组扩大两倍,当做普通问题处理。方法二:借助栈思想。就是上述代码,只是不太优雅。参考代码中的nextGreaterElementsV3。
代码

71 Simplify Path

问题:这是关于文件夹路径简化的问题。
这里写图片描述
总结的规律是:大小写区分;”/字母”这是一级目录; “/.”可以忽略 ;”/..”回退一级目录。题目思考的思路是按照一个字符一个字符去思考。思考遇到不同类型的字符,应该做什么操作。代码经过不断合并if条件,得到最后的代码。

public String simplifyPath(String path) {Stack<String> dirStack = new Stack<String>();int n = path.length();for (int i = 0; i < n; i++) {char ch = path.charAt(i);if (ch!='/') {int end = i + 1;while (end < n && path.charAt(end) !='/') {end++;}String str = path.substring(i,end);if(str.equals("..")){if(!dirStack.isEmpty()){dirStack.pop();}}else if(!str.equals(".")){dirStack.push(str);}i = (end > i + 1 ? end - 1 : i);}}String r = "";for(String dir : dirStack){r = r + "/"+dir;}return r==""?"/":r;}

学习:有人思考的角度是把字符串按/分隔后,考虑字符的有效性和无效性。代码简洁了很多。只是执行速度慢了。

public String simplifyPathV2(String path) {Deque<String> stack = new LinkedList<String>();for(String str : path.split("/")){if(str.equals("..") && !stack.isEmpty()){stack.pop();}else if(!str.equals("..") && !str.equals(".") && !str.equals("")){stack.push(str);}}String r = "";for(String dir : stack){r = "/"+dir+r;}return r==""?"/":r;}

代码

173 Binary Search Tree Iterator

问题:这是关于二分查找树的一个遍历器,要求实现hasNext方法和next方法,时间要求平均是O(1),空间要求是O(h),h是树的高度。根据二分查找树的定义,我们知道所有左子树节点的值小于根节点;所有右子树节点的值大于根节点。当next方法要求依次返回最小值的时候,我们知道肯定是先返回左子树的值,再返回节点值,最后返回右子树上的值。只是在实现的时候不能在空间要求下实现。
学习:思路一:用stack存储从根节点开始的所有左节点。当next被调用的时候,直接从stack pop节点tmpNode,返回tmpNode的值。在返回之前,将tmpNode.right作为根节点再次处理存入stack。我的问题是总想弄一个curNode,想怎么在三种状态之间切换(左子节点、当前节点值、右子节点)

public class BSTIteratorV2 {private Stack<TreeNode> stack = new Stack<TreeNode>();public BSTIteratorV2(TreeNode root) {fillStack(root);}private void fillStack(TreeNode node) {for(;node!=null;node = node.left){stack.push(node);}}/** @return whether we have a next smallest number */public boolean hasNext() {return !stack.isEmpty();}/** @return the next smallest number */public int next() {TreeNode tmpNode = stack.pop();fillStack(tmpNode.right);return tmpNode.val;}
}

学习:思路二:看到一个有当前节点版本的。当前节点与要返回值的节点不是一个节点。这是重点

public class BSTIteratorV3 {private Stack<TreeNode> stack;private TreeNode cur = null;public BSTIteratorV3(TreeNode root){cur = root;stack = new Stack<TreeNode>();}public boolean hasNext() {return !stack.isEmpty() || cur !=null;}public int next(){while(cur!=null){stack.push(cur);cur = cur.left;}TreeNode node = stack.pop();//这一部是没有想到的cur = node.right;return node.val;}
}

94 Binary Tree Inorder Traversal

问题:中序遍历二叉树。整个解题思路与上一题目完全相同。可以实现一下递归版本与迭代版本。
代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第三十期:简单好用的9个电脑必备工具!让你轻松10倍

下面 9 款工具都是精心挑选的电脑必备神器&#xff0c;涵盖你需要的各个方面&#xff0c;无论是安全防护、文件查找、解压加密还是娱乐都在其中&#xff1b;最最最重要的是&#xff0c;它们不但各个功能强大&#xff0c;而且非常轻便&#xff0c;没有弹窗广告、没有捆绑安装、也…

【数据结构与算法】字符串匹配 BF算法 RK算法

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 一、BF 算法 1&#xff0c;BF算法是Brute Force的缩写&#xff0c;中文译作暴力匹配算法&#xff0c;也叫朴素匹配算法。 2&#xff0c;两个概念&#xff1a;主串和模式串 如在字符串…

第三十一期:大数据分析师学习入门,10个数据可视化技巧

在这篇文章&#xff0c;我想和大家分享 10 个基本的中级和高级的绘图工具。我发现在现实生活中&#xff0c;当涉及到绘图解释你的数据时&#xff0c;这些工具非常有用。 作者&#xff1a;加米谷大数据来源&#xff1a;今日头条 我必须对你说实话&#xff1a;当我学习数据科学时…

[Leetcode][第491题][JAVA][递增子序列][回溯][RK算法]

【问题描述】[中等] 【解答思路】 1. 二进制枚举 哈希 复杂度 class Solution {List<Integer> temp new ArrayList<Integer>();List<List<Integer>> ans new ArrayList<List<Integer>>();Set<Integer> set new HashSet<In…

第五十七期:小型企业将如何从5G中受益

在足够多的新设备进入主流市场之前&#xff0c;5G已经在许多领域引起了越来越多的关注。从IT、零售、交通和制造业到医疗、娱乐、教育和农业&#xff0c;几乎每个行业都将在某种程度上受到5G的影响。 作者&#xff1a;李雪薇来源&#xff1a;IT168网站 在足够多的新设备进入主…

第三十二期:MySQL常见的图形化工具

MySQL作为一款非常流行的、开源的关系型数据库&#xff0c;应用非常广泛。因为MySQL开源的缘故&#xff0c;图形化管理维护工众多&#xff0c;除了系统自带的命令行管理工具之外&#xff0c;还有许多其他的图形化管理工具&#xff0c;这里介绍几个经常使用的MySQL图形化管理工具…

centos7 源码安装goaccess

1. 使用yum安装在不同服务器上可能失败, 推荐使用源码安装goaccess # 安装依赖 yum install -y ncurses-devel GeoIP-devel.x86_64 tokyocabinet-devel openssl-devel# 下载源码包并安装 cd /usr/local/software wget http://tar.goaccess.io/goaccess-1.3.tar.gz tar -xvf goa…

【数据结构与算法】字符串匹配 BM算法

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 BM算法 BM算法的核心思想是通过将模式串沿着主串大踏步的向后滑动&#xff0c;从而大大减少比较次数&#xff0c;降低时间复杂度。而算法的关键在于如何兼顾步子迈得足够大与无遗漏&…

第五十八期:AI艺术日渐繁荣,未来何去何从?

本文的配图都是AI艺术领域领导者、德国艺术家马里奥克林格曼(Mario Klingemann)利用人工智能创作的作品。 利用人工智能创作而成的画作近年来越来越受瞩目&#xff0c;有的作品甚至能在知名拍卖行拍得高价。但这类作品仍有不少问题需要解答&#xff0c;比如它的作者是开发出算…

【数据结构与算法】字符串匹配 KMP 算法

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 KMP 算法 KMP 算法是根据三位作者&#xff08;D.E.Knuth&#xff0c;J.H.Morris 和 V.R.Pratt&#xff09;的名字来命名的&#xff0c;算法的全称是 Knuth Morris Pratt 算法&#x…

第五十九期:商用数据库之死:Oracle 面临困境

作者&#xff1a;John Freeman、Fred McClimans 和 Zach Mitchell 我们预计到 2021 年&#xff0c;年产值 296 亿美元的商业数据库市场会收缩 20% 至 30%&#xff0c;认为 Oracle 无法让收入来源足够快地实现转型&#xff08;从传统的商业数据库转向基于云的订购产品&#xff0…

第六十期:华为:希望把VR/AR打造成下个智能手机产业

网易科技讯 10 月 19 日消息&#xff0c;2019 世界 VR 产业大会在江西省南昌市举行。华为轮值董事长郭平发表了《打造 VR/AR 信息高速公路&#xff0c;支撑产业繁荣》的主题演讲。郭平认为&#xff0c;VR/AR 将成为 5G 时代的首批应用&#xff0c;与 5G 产业发展节奏高度匹配并…

【数据结构与算法】字符串匹配 AC自动机

单模式串匹配 BF 算法和 RK 算法 BM 算法和 KMP 算法多模式串匹配算法 Trie 树和 AC 自动机 AC 自动机 AC 自动机实际上就是在 Trie 树之上&#xff0c;加了类似 KMP 的 next 数组&#xff0c;只不过此处的 next 数组是构建在树上罢了。 AC 自动机的构建 将多个模式串构建成…

第六十一期:中国农民花3000块,发明史上最牛输入法!曾火遍中国20年

投递人 itwriter “王旁青头戋(兼)五一&#xff0c;土十二干士寸雨” 如果你还能熟练的背出这段口诀&#xff0c;恭喜你&#xff0c;又暴露年龄了。 倒回到十几年前&#xff0c;在刀哥被老师带到穿鞋套才能进神秘的机房&#xff0c;练习打字的时候&#xff0c;会五笔的人简直是…

第六十二期:腾讯云发布“小程序·云开发十大优秀实践”:猫眼、唯品会等入选

作者&#xff1a;周小白 【TechWeb】10 月 19 日消息&#xff0c;今日&#xff0c;腾讯云首次对外公布了“小程序云开发十大优秀实践”&#xff0c;包括白鹭引擎、千墨科技、腾讯新闻、即速应用、微盟、唯品会、猫眼、香格里拉、微信读书、微信支付等&#xff0c;涉及多个行业。…

[Leetcode][第17题][JAVA][电话号码的字母组合][回溯]

【问题描述】[中等] 【解答思路】 用哈希表/数组存储每个数字对应的所有可能的字母&#xff0c;然后进行回溯操作。 回溯过程中维护一个字符串&#xff0c;表示已有的字母排列&#xff08;如果未遍历完电话号码的所有数字&#xff0c;则已有的字母排列是不完整的&#xff09;…

(68)zabbix windows性能计数器使用详解

概述 windows下的性能计数器让zabbix监控更加轻松&#xff0c;直接获取性能计数器的数值即可完成windows监控。性能计数器如下&#xff1a; 1perf_counter["\Processor(0)\Interrupts/sec"]或 1perf_counter["\Processor(0)\Interrupts/sec", 10]获取所有性…

第六十三期:微软与阿里云合作推出“开放应用模型(OAM)”

投递人 itseeker 英文原文&#xff1a;Announcing the Open Application Model (OAM) 原文标题&#xff1a;微软与阿里云合作推出“开放应用模型&#xff08;OAM&#xff09;” 用于 Kubernetes 及更多平台的应用开发、运行的开放标准 Kubernetes 已经成为业界领先的容器编排环…

【数据结构与算法】【算法思想】贪心算法

贪心算法 回溯算法 分治算法 动态规划 四种基本的算法思想&#xff1a;贪心算法&#xff0c;分治算法&#xff0c;回溯算法&#xff0c;动态规划&#xff0c;他们不是具体算法&#xff0c;常用来指导我们设计具体的算法和编码等。 一&#xff1a;贪心算法有很多经典应用 霍夫…

第六十四期:微软将不再把 .NET Framework API 移植到 .NET Core 3.0

投递人 itwriter 目前 .NET Core 3.0 拥有的 API 总数约为 .NET Framework API 的 80%&#xff0c;剩下尚未从 .NET Framework 移植到 .NET Core 的 API&#xff0c;微软考虑以开源的形式发布。 微软方面表示&#xff0c;通过 .NET Core 3.0&#xff0c;他们现在已具备轻松移植…