算法:有效的括号

有效的括号

给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。

示例 1:
输入:s = “()”
输出:true

示例 2:

输入:s = “()[]{}”
输出:true

示例 3:
输入:s = “(]”
输出:false

示例 4:
输入:s = “([)]”
输出:false

示例 5:
输入:s = “{[]}”
输出:true

提示:

1 <= s.length <= 104 s 仅由括号 ‘()[]{}’ 组成

leedtcode 链接

1.分析

根据题意我们可以得出:

1.有效的字符串长度一定是偶数,否则无效
2.右括号前边必须是对应的左括号才有效,否则无效

3.我们可以使用栈来看数据是否对应,比如,遇左括号就压入栈
4.如遇右括号,弹出栈顶,两者对应,则抵消
5.最后栈中还有数据,证明没有全部抵消,字符串无效

2.题解

下面我们使用两个方法来完成这道题

解法1 - 使用 es6的 map

var isValid = function(s) {
	let l = s.length
	if (l % 2 !== 0 ) { return false } // 1.字符串长度不是偶数直接返回 false
	let map = new Map([['}', '{'], [')', '('], [']', '[']])
	// 2.使用 map 将括号映射成如下键值对(因为我们通过右括号判断左括号):
	// Map(3)  {')' => '(', ']' => '[', '}' => '{'}
	let stack = []
	for (let i of s) { // 循环遍历当前字串
		if (map.get(i)) { // 3.判断有无当前键对应的值,因为我们是通过右括号判断左括号,但字串顺序是从左到右的,所以前几轮判断会走 else
			if (stack[stack.length - 1] === map.get(i)) { // 4.判断右括号时,找对应括号需从数组倒序比较,即从最后一个元素依次开始
				stack.pop() // 4.如果相等即弹出
			} else {
				return false // 4.否则返回false开始下一轮循环
			}
		} else {
			stack.push(i) //  3.如字串'[({})]'前三轮会将'[({'写入数组
		}
	}
	return !stack.length;
}

在这里插入图片描述

走过的坑:

1.map 用法

map 生成键值对,和数组的转换
此例中,要想生成 {’)’ => ‘(’, ‘]’ => ‘[’, ‘}’ => ‘{’}的映射关系,需要在 new Map()中嵌套数组,加一个’[ ]’

2.for in 和 for of 区别

for…of适用遍历数/数组对象/字符串/map/set等拥有迭代器对象的集合.但是不能遍历对象, 因为没有迭代器对象.与forEach()不同的是,它可以正确响应break、continue和return语句,for-of循环不支持普通对象,不建议使用 for-in 属性遍历数组等,因为,for in遍历的是数组的索引(即键名),而for of遍历的是数组元素值。

如果你想迭代一个对象的属性,你可以用for-in循环(这也是它的本职工作)或内建的Object.keys()方法:

Array pop()方法

pop() 方法移除数组的最后一个元素,并返回该元素。

解法2 - switch case 或者 if 按条件判断

把左括号全部推入栈中,到右括号时依次从栈顶弹出比较

let isValid = function(s) {
	let l = s.length;
	if (l % 2 !== 0) { return false };
	let stack = []
	for (let i of s) {
		switch (i) {
			case '{':
			case '[':
			case '(':
				stack.push(i);
				break;
			case '}':
				if(stack.pop() !== '{') return false;
				break;
			case ']':
				if(stack.pop() !== '[') return false;
				break;
			case ')':
				if(stack.pop() !== '(') return false;
				break;
			}
		}
		return !stack.length;
}

在这里插入图片描述

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值