hello大家好, 分别是 《有效括号判断》、《链表合并排序》、《计数排序算法》、《二叉树前序排序》、《回文数判断》
一、有效括号判断
说明: 给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。 有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合
例如: '([{}])' true、 '[}' false
思路:
- 可以使用栈结构进行进行存储输入的符合括号开头的字符,如
(、[、{这些字符 - 当匹配到非开头的字符时,此时从栈顶拿出元素进行比较不符合则退出符合则继续
- 核心原理是利用栈的先进后出的原则进行编码
实现
function valid(str) {
// 将输入的字符进行数组化
const arr = str.split("");
const stack = [];
const staticSymbol = { "(": ")", "[": "]", "{": "}" };
for (let i = 0; i < arr.length; i++) {
const symbol = arr[i];
// 判断是否是开头字符
if (Object.keys(staticSymbol).indexOf(symbol) >= 0) {
stack.push(arr[i]);
} else {
// 当出现尾字符时,栈中没有数据说明不对称
if (!stack.length) return false;
const match = stack.pop();
if (staticSymbol[match] !== arr[i]) {
return false;
}
}
}
// 比较完之后,栈中还有数据则不对称
if (stack.length) return false;
return true;
}
二、链表合并排序
说明: 输入两个递增排序的数组并转成链表,合并这两个链表并使新链表中的节点仍然是递增排序的, 并且输出数组。
例如:输入[1,2,3] [2,3,4] 输出:[1,2,2,3,3,4]
思路
- 将第二个链表以插入排序的方式合并
实现
// 链表构造函数
function ListNode(val) {
this.val = val;
this.next = null;
}
// 数组转链表
function generateList (array) {
let fakeHead = new ListNode(0);
let current = fakeHead;
for (let index = 0; index < array.length; index++) {
current.next = { val: array [index], next: null};
current = current.next;
}
return fakeHead.next;
}
// 链表转数组
function generateArray (list) {
let res = []:
while (list) {
res.push(list.val);
list = list.next;
}
return res;
}
function mergeList(list1,list2) {
let curList2 = list2;
let curList1 = list1;
let newList = list1;
while(curList2) {
// 两层循环 利用插入排序
while(curList1 && curList2) {
if(curList2.val > curList1.val) {
const temp = curList1.next;
curList1.next = curList2
const temp2 = curList2.next
curList2.next = temp;
curList1 = curList2.next
curList2 = temp2
break
}
}
}
}
三、计数排序算法
说明: 使用计数的方式实现输入的数组,变成有序
思路
- 找出输入数组的最大值n, 创建n+1大小的数组进行计数
- 循环计数数组,收集出现次数的数字完成排序(升序向前遍历、降序向后遍历)
实现
function countSort(arr) {
// 找出最大值
const max = arr.reduce((pre, cur) => (pre < cur ? cur : pre), 0);
// 创建计数组数并赋值0
const counter = new Array(max + 1).fill(0);
const result = [];
for (let i = 0; i < arr.length; i++) {
counter[arr[i]]++;
}
counter.forEach((c, i) => {
while (c) {
result.push(i);
c--;
}
});
return result;
}
四、二叉树前序排序
思路
- 采用递归的形式分别判断 left 和 right 是否有值
实现
// 将数组转换成二叉树
function convertBinaryTree(arr) {
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);
}
};
arr.forEach((val) => {
let node = {
val: val,
left: null,
right: null,
};
if (root) insertNode(root, node);
else root = node;
});
return root;
}
// 前序排序
function beforeOrder(str) {
const arr = str.split(",");
const root = convertBinaryTree(arr);
const result = [];
// 使用递归将目标节点值push
function find(node) {
if (!node) return;
if (node) {
result.push(node.val);
}
if (node.left) {
find(node.left);
}
if (node.right) {
find(node.right);
}
}
find(root);
return result;
}
五、回文数判断
说明: 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
思路
- 我们不采用js数组自带的reverse函数进行反排序
- 既然是回文数那么满足 arr[i] == arr[arr.length - 1 -i] 这个公示否则即不是回文数
实现
function palindrome(num) {
if (num < 0) return false;
else if (num < 10) return true;
const arr = `${num}`.split("");
// 当数字个数为基数时向下取整, 避免循环到中间值
for (let i = 0; i < Math.floor(arr.length / 2); i++) {
if (arr[i] !== arr[arr.length - 1 - i]) {
return false;
}
}
return true;
}
最后
谢谢大家的观看。我是算法小菜鸟在学习过程中记录自己的学习思路,有错误的地方希望大家能给与指正。如有更好的算法写法也可以在评论与我交流谢谢!