算法练习笔记(二)
10.16
①有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
示例 4:
输入:s = "([)]"
输出:false
示例 5:
输入:s = "{[]}"
输出:true
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/valid-parentheses
代码
:
const leftToRight = {
"{":"}",
"[":"]",
"(":")"
}
var isValid = function(s){
//结合题意,空字符串无条件判断为true
if(!s)return true
//初始化数组stack
let stack = []
//缓存字符串长度
const len = s.length
//遍历字符串
for(let i=0;i<len;i++){
//缓存单个字符
const ch = s[i]
//判断是否是左括号
if(ch==="("||ch==="["||ch==="{"){
stack.push(leftToRight[ch])
}else{
//若栈不为空,且栈顶的左括号没有和当前字符匹配上,那么判为无效
if(!stack.length||stack.pop()!==ch){
return false
}
}
}
//若所有的括号都能配对成功,那么最后栈应该是空的
return !stack.length
}
②二叉树的中序遍历
给定一个二叉树的根节点 root ,返回它的 中序 遍历。
示例 1:
输入:root = [1,null,2,3]
输出:[1,3,2]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal
代码
:
var inorderTraversal = function(root,res=[]){
if(!root){
return
}
inorderTraversal(root.left,res)
res.push(root.val)
inorderTraversal(root.right,res)
return res
}
10.17
①最小栈
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
push(x) —— 将元素 x 推入栈中。
pop() —— 删除栈顶的元素。
top() —— 获取栈顶元素。
getMin() —— 检索栈中的最小元素。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/min-stack
思路
:
变O(n)为O(1),时间效率的提升,意味着要付出更多的空间占用作为代价。可以考虑再搞个栈(stack2)出来作为辅助,让这个栈去容纳当前的最小值。
代码
:
var Minstack = function(){
this.stack = []
//辅助栈
this.stack2 = []
}
Minstack.prototype.push = function(val){
this.stack.push(val)
//若入栈的值小于当前最小值,则推入辅助栈栈顶
if(this.stack2.length===0||this.stack2[this.stack2.length-1]){
this.stack2.push(val)
}
}
Minstack.prototype.pop = function(val){
//若出栈的值和当前最小值相等,那么辅助栈也要对栈顶元素进行出栈,确保最小值的有效性
if(this.stack.pop()===this.stack2[this.stack2.length-1]){
this.stack2[this.stack2.length-1]
}
}
Minstack.prototype.top = function(){
return this.stack[this.stack.length-1]
}
Minstack.prototype.getMin = function(){
//辅助栈的栈顶,存的就是目标中的最小值
return this.stack2[this.stack2.length-1]
}
②回文链表
给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:head = [1,2,2,1]
输出:true
示例 2:
输入:head = [1,2]
输出:false
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list
思路
:遍历链表存进数组,再用双指针从数组首尾开始判断
var isPalindrome = function(head){
const arr = []
while(head!=null){
arr.push(head.val)
head = head.next
}
let left = 0,right = arr.length-1
while(left<right){
if(arr[left]!==arr[right])return false
left++
right--
}
return true
}
10.18
①逆波兰表达式求值
根据 逆波兰表示法,求表达式的值。
有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。
说明:
整数除法只保留整数部分。
给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。
示例 1:
输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9
示例 2:
输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6
示例 3:
输入:tokens = ["10","6","9","3","+","-11","","/","","17","+","5","+"]
输出:22
解释:
该算式转化为常见的中缀算术表达式为:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22
逆波兰表达式:
逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。
平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。
逆波兰表达式主要有以下两个优点:去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
:
题目自己已给出_
代码
:
var operation = {
"+":function(x,y){return x+y},
"-":function(x,y){return y-x},
"*":function(x,y){return x*y},
"/":function(x,y){return parseInt(y/x)}
}
var evalRPN = function(tokens){
const len = tokens.length
const stack = []
for(let i=0;i<len;i++){
if(tokens[i] in operation){
let x = +stack.pop()
let y = +stack.pop()
stack.push(operation[tokens[i]](x,y))
}else{
stack.push(tokens[i])
}
}
return stack[0]
}
②基本计算器 II
给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
示例 1:
输入:s = "3+2*2"
输出:7
示例 2:
输入:s = " 3/2 "
输出:1
示例 3:
输入:s = " 3+5 / 2 "
输出:5
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/basic-calculator-ii
代码
:
var calculate = function(s){
let stack = []
let n = '',f = '+'
for(let i=0;i<s.length||n;i++){
if(s[i]===' ')continue
if(/\D/.test(s[i])){
switch(f){
case '+':
stack.push(n)
break;
case '-':
stack.push(-n)
break;
case '*':
stack.push(stack.pop() * n)
break;
case '/':
stack.push(stack.pop() / n | 0)
}
f = s[i]
n = ''
}else{
n += s[i]
}
}
return stack.reduce((p,v)=>p+(v|0),0)
}
10.19
扁平化嵌套列表迭代器
给你一个嵌套的整数列表 nestedList 。每个元素要么是一个整数,要么是一个列表;该列表的元素也可能是整数或者是其他列表。请你实现一个迭代器将其扁平化,使之能够遍历这个列表中的所有整数。
实现扁平迭代器类 NestedIterator :
NestedIterator(List
int next() 返回嵌套列表的下一个整数。
boolean hasNext() 如果仍然存在待迭代的整数,返回 true ;否则,返回 false 。
你的代码将会用下述伪代码检测:
initialize iterator with nestedList
res = []
while iterator.hasNext()
append iterator.next() to the end of res
return res
如果 res 与预期的扁平化列表匹配,那么你的代码将会被判为正确。
示例 1:
输入:nestedList = [[1,1],2,[1,1]]
输出:[1,1,2,1,1]
解释:通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,1,2,1,1]。
示例 2:
输入:nestedList = [1,[4,[6]]]
输出:[1,4,6]
解释:通过重复调用 next 直到 hasNext 返回 false,next 返回的元素的顺序应该是: [1,4,6]。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/flatten-nested-list-iterator
代码
/**
* // This is the interface that allows for creating nested lists.
* // You should not implement it, or speculate about its implementation
* function NestedInteger() {
*
* Return true if this NestedInteger holds a single integer, rather than a nested list.
* @return {boolean}
* this.isInteger = function() {
* ...
* };
*
* Return the single integer that this NestedInteger holds, if it holds a single integer
* Return null if this NestedInteger holds a nested list
* @return {integer}
* this.getInteger = function() {
* ...
* };
*
* Return the nested list that this NestedInteger holds, if it holds a nested list
* Return null if this NestedInteger holds a single integer
* @return {NestedInteger[]}
* this.getList = function() {
* ...
* };
* };
*/
/**
* @constructor
* @param {NestedInteger[]} nestedList
*/
var NestedIterator = function(nestedList) {
this.list = [];
this.resetList(nestedList);
};
//将二维数组转为一维数组
NestedIterator.prototype.resetList = function(arr) {
for (let i = 0; i < arr.length; i++) {
if (arr[i].isInteger())
this.list.push(arr[i].getInteger())
else
this.resetList(arr[i].getList())
}
};
/**
* @this NestedIterator
* @returns {boolean}
*/
NestedIterator.prototype.hasNext = function() {
return this.list.length > 0;
};
/**
* @this NestedIterator
* @returns {integer}
*/
NestedIterator.prototype.next = function() {
return this.list.shift();
};