• 算法练习笔记(二)


    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();
    };
    
  • 相关阅读:
    JAVA关于byte数组与String转换的问题
    XML快速注释
    const常量与define宏定义的区别
    IOS进度渐变图层CAGradientLayer
    UIView常用的一些方法小记之setNeedsDisplay和setNeedsLayout
    UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
    细说UIScrollView上的Touch 事件
    ios TableView那些事(二十 九)UITableViewController 粘合性
    UITableViewController子控制器的使用方法
    iOS: 如何在工程中设置 DEBUG 模式?
  • 原文地址:https://www.cnblogs.com/Small-Windmill/p/15413828.html
Copyright © 2020-2023  润新知