返回
使用 JavaScript 算法解决经典问题:有效括号、合并链表、计数排序、二叉树前序遍历
前端
2023-11-03 12:35:51
有效括号
问题
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效括号的定义如下:
- 空字符串为有效括号
- 如果一个字符串 A 是有效括号,那么 A 的前缀 A + B 和 A 的后缀 B + A 也是有效括号
- 如果 A 和 B 都是有效括号,那么 AB 也是有效括号
示例 1:
输入:s = "()"
输出:true
示例 2:
输入:s = "()[]{}"
输出:true
示例 3:
输入:s = "(]"
输出:false
代码实现:
/**
* 判断字符串中的括号是否有效
*
* @param {string} s
* @return {boolean}
*/
const isValid = (s) => {
if (s.length === 0) {
return true;
}
const stack = [];
for (let i = 0; i < s.length; i++) {
const char = s[i];
if (char === '(' || char === '{' || char === '[') {
stack.push(char);
} else {
const top = stack.pop();
if (
(char === ')' && top !== '(') ||
(char === '}' && top !== '{') ||
(char === ']' && top !== '[')
) {
return false;
}
}
}
return stack.length === 0;
};
时间复杂度:
O(n),其中 n 是字符串 s 的长度。
空间复杂度:
O(n),其中 n 是字符串 s 的长度。
合并链表
问题:
合并两个有序链表。
示例 1:
输入:l1 = [1, 2, 4], l2 = [1, 3, 4]
输出:[1, 1, 2, 3, 4, 4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
代码实现:
/**
* 合并两个有序链表
*
* @param {ListNode} l1
* @param {ListNode} l2
* @return {ListNode}
*/
const mergeTwoLists = (l1, l2) => {
if (l1 === null) {
return l2;
}
if (l2 === null) {
return l1;
}
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
};
时间复杂度:
O(n + m),其中 n 是链表 l1 的长度,m 是链表 l2 的长度。
空间复杂度:
O(n + m),其中 n 是链表 l1 的长度,m 是链表 l2 的长度。
计数排序
问题:
给定一个包含 n 个整数的数组 nums,对数组进行排序。
示例 1:
输入:nums = [5, 3, 1, 2, 4]
输出:[1, 2, 3, 4, 5]
示例 2:
输入:nums = [5, 4, 3, 2, 1]
输出:[1, 2, 3, 4, 5]
示例 3:
输入:nums = []
输出:[]
代码实现:
/**
* 对一个数组进行计数排序
*
* @param {number[]} nums
* @return {number[]}
*/
const countingSort = (nums) => {
if (nums.length === 0) {
return [];
}
const maxValue = Math.max(...nums);
const minValue = Math.min(...nums);
const range = maxValue - minValue + 1;
const countArray = new Array(range).fill(0);
for (let i = 0; i < nums.length; i++) {
const index = nums[i] - minValue;
countArray[index]++;
}
let sortedIndex = 0;
for (let i = 0; i < range; i++) {
while (countArray[i] > 0) {
nums[sortedIndex++] = minValue + i;
countArray[i]--;
}
}
return nums;
};
时间复杂度:
O(n + k),其中 n 是数组 nums 的长度,k 是数组 nums 中的最大值和最小值之差。
空间复杂度:
O(n + k),其中 n 是数组 nums 的长度,k 是数组 nums 中的最大值和最小值之差。
二叉树前序遍历
问题描述:
给定一棵二叉树,进行前序遍历。
示例 1:
输入:root = [1, null, 2, 3]
输出:[1, 2, 3]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
代码实现:
/**
* 对一棵二叉树进行前序遍历
*
* @param {TreeNode} root
* @return {number[]}
*/
const preorderTraversal = (root) => {
if (root === null) {
return [];
}
const result = [];
const stack = [root];
while (stack.length > 0) {
const node = stack.pop();
result.push(node.val);
if (node.right !== null) {
stack.push(node.right);
}
if (node.left !== null) {
stack.push(node.left);
}
}
return result;
};
时间复杂度:
O(n),其中 n 是二叉树的节点数。
空间复杂度:
O(n),其中 n 是二叉树的节点数。