算法练习笔记(二)

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 nestedList) 用嵌套列表 nestedList 初始化迭代器。
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();
};
posted @ 2021-10-16 12:21  小风车吱呀转  阅读(25)  评论(0编辑  收藏  举报