「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」
第一题:有效括号
题目描述:
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
思路:
遍历字符串所有元素,再遍历过程中利用额外数组list空间保存左括号字符串;
当遍历过程中遇到左括号字符串,将字符串放入list;
初始时声明一个变量sign为true;如果过程中没有将sign赋值为false,则字符串可能是有效括号;
当便利过程中遇到右括号,判断list数组中最后一位与当前字符串是否可以组成一对字符串;
然后,如果可以凑成一对有效括号,删除数组中最后一位;否则将sign设置为false;
最后,如果sign为true并且list.length为0;字符串是有效的,否则是无效的。
代码如下
const s = readline()
const len = s.length
let sign = true
const list = []
for (let i = 0; i < len; i++) {
const c = s[i]
if (c === '(' || c === '{' || c === '[') {
list.push(c)
} else {
const l = list.length - 1
const t = list[l]
if (
(c === ')' && t === '(') ||
(c === ']' && t === '[') ||
(c === '}' && t === '{')
) {
list.pop()
} else {
sign = false
}
}
}
console.log(sign && list.length === 0)
第二题
第三题:叉树的前序遍历
递归
怎么递归呢?
想象一下,一个二叉树通过前序遍历是不是这样一个路径:根节点——>左节点1——>右节点1;然后左节点1——>左节点11——>右节点12;
典型的递归思路呀;
如果节点左侧有数据,将左侧数据作为参数调用自身;
非递归
递归数据量大的话消耗大量内存容易爆栈;
非递归需要用到额外空间,将而二叉树数据存放在数组list尾部;
取出数组尾部第一个节点;
若当前左侧有数据,将当前节点左侧再次丢入数组list尾部;
一次进行上述操作;当list长度为0时;即可遍历整个二叉树
function convertBinaryTree(list) {
let root
let insertNode = function (parentNode, childNode) {
if (!childNode || childNode.val === '') return
if (childNode.val < parentNode.val) {
if (parentNode.left === null) {
parentNode.left = childNode
} else {
insertNode(parentNode.left, childNode)
}
} else {
if (parentNode.right === null) {
parentNode.right = childNode
} else {
insertNode(parentNode.right, childNode)
}
}
}
list.forEach((val) => {
let node = {
val,
left: null,
right: null,
}
if (root) {
insertNode(root, node)
} else {
root = node
}
})
return root
}
//将数组构建为二叉树
const tree = convertBinaryTree(readline().split(','))
// 递归方法
const start = (node) => {
if (!node) return
result.push(node.val)
start(node.left)
start(node.right)
}
const result = []
start(tree)
console.log(result.join(','))
// 非递归方法
const list = [tree];
let array = []
while(list.length){
const current = list.pop()
array.push(current.val);
current.left && list.push(current.left);
current.right && list.push(current.right);
}
第四题:计数排序
思路
利用额外空间,将原数组中数值作为新数组下标,数值出现的次数作为新数组下标位置的值;
比如:
数组 list = [3,6,4,3];
生成新数组为 newList = [empty,empty,empty,2,1,empty,1];
原数组3出现了2次,所以新数组下标为3的位置,设置为2;
再整理一下新数组就可以得到排序数组;
比如以上数据:
假设结果数组为result = [];
原数组最小值min = 3;
原数组最大值max = 6;
遍历从3开始,到6结束;
执行到3,在新数组下标为3数字是2,将2个3放入result;
执行到4,在新数组中下标为4的数值是1,将1个4放入result;
执行到5,在新数组中下标为5的数值是enpty,不做操作;
执行到6,在新数组中下标为6的数值是1,将1个6放入result;
具体代码如下:
const list = JSON.parse(readline() || '[]')
//计数
const len = list.length
const array = []
for (let i = 0; i < len; i++) {
const idx = list[i]
array[idx] = (array[idx] || 0) + 1
}
const min = Math.min(...list)
const max = Math.max(...list)
const result = []
for (let i = min; i <= max; i++) {
if (array[i] > 0) {
result.push(Array(array[i]).fill(i))
array[i] = 0
}
}
console.log(result.join(','))
第五题:回文数
题目描述:判断一个字符串是否时回文字符
思路:
思路及其简单;
首先,负数肯定不是回文字符串,所以第一步将负数排除;
第二步:既然回文,将字符串反转一定与原字符串相同;
所以,代码如下:
const s = readline()
const n = Number(s)
if (n < 0) {
console.log(false)
} else {
const len = s.length
let t = ''
for (let i = len - 1; i >= 0; i--) {
t += s[i]
}
console.log(t === s)
}