有效括号
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。
const left = ['(', '{', '[']
const map = {
')': '(',
'}': '{',
']': '['
}
function isValid(str) {
var arr = str.split('')
var stack = []
for (var i = 0; i < arr.length; i++) {
var item = arr[i]
if (stack.length === 0 && left.includes(item) === -1) {
return false
}
if (left.includes(item)) {
stack.push(item)
} else {
if (map[item] !== stack.pop()) {
return false
}
}
}
if (stack.length) {
return false
}
return true
}
console.log(isValid("()"))//true
console.log(isValid("()[]{}"))//true
console.log(isValid("(]"))//false
console.log(isValid("([)]"))//false
console.log(isValid("{[]}"))//true
回文数
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
var isPalindrome = function() {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,
// 则其第一位数字也应该是 0
// 只有 0 满足这一属性
if (x < 0 || (x % 10 === 0 && x !== 0)) {
return false;
}
let revertedNumber = 0;
while (x > revertedNumber) {
revertedNumber = revertedNumber * 10 + x % 10;
x = Math.floor(x / 10);
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x === revertedNumber || x === Math.floor(revertedNumber / 10);
};
利用高阶函数
var isPalindrome = function(x) {
if (x < 0 || (x % 10 === 0 && x !== 0)) {
return false;
}
return Array.from(String(x)).reverse().join('') === String(x)
};
合并排序链表
给定一个链表数组,每个链表都已经按升序排列。
请将所有链表合并到一个升序链表中,返回合并后的链表。
//js并没有链表结构,所以我们需要自己构建链表结构,步骤如下
//数组转链表
//链表合并排序
//链表结果转数组 以数组方式展示
function ListNode(val) {
this.val = val;
this.next = null;
}
//数组转链表函数
function ListNode(val) {
this.val = val;
this.next = null;
}
//数组转链表函数
function generateList(arr) {
let fakeHead = new ListNode(0);
let current = fakeHead;
for (let index = 0; index < arr.length; index++) {
current.next = { val: arr[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;
}
var mergeKLists = function (lists) {
lists = lists.map(item => generateList(item))
var newList = new ListNode('head')
var lastList = newList
while (lists.length > 0) {
var nullIndex = 0;
let min = null
for (let i = 0; i < lists.length; i++) {
var item = lists[i]
if (min === null) {
min = item.val;
nullIndex = i
continue;
}
if (min > item.val) {
min = item.val
nullIndex = i
continue;
}
}
lastList.next = new ListNode(min)
lastList = lastList.next
lists[nullIndex] = lists[nullIndex].next
if (lists[nullIndex] === null) {
lists.splice(nullIndex, 1)
}
}
return generateArray(newList.next)
}
var lists = [
[1, 3, 5],
[3, 5, 7],
[1, 2, 3],
]
console.log(mergeKLists(lists))
//输入[[1,3,5],[3,5,7],[1,2,3]]
//输出[1, 1, 2, 3, 3, 3, 5, 5, 7]
解法二
/**
* @param {ListNode[]} lists
* @return {ListNode}
*/
var mergeKLists = function (lists) {
// 当是空数组的情况下
if (!lists.length) {
return null;
}
// 合并两个排序链表
const merge = (head1, head2) => {
let dummy = new ListNode(0);
let cur = dummy;
// 新链表,新的值小就先接谁
while (head1 && head2) {
if (head1.val < head2.val) {
cur.next = head1;
head1 = head1.next;
} else {
cur.next = head2;
head2 = head2.next;
}
cur = cur.next;
}
// 如果后面还有剩余的就把剩余的接上
cur.next = head1 == null ? head2 : head1;
return dummy.next;
};
const mergeLists = (lists, start, end) => {
if (start + 1 == end) {
return lists[start];
}
// 输入的k个排序链表,可以分成两部分,前k/2个链表和后k/2个链表
// 如果将这前k/2个链表和后k/2个链表分别合并成两个排序的链表,再将两个排序的链表合并,那么所有链表都合并了
let mid = (start + end) >> 1;
let head1 = mergeLists(lists, start, mid);
let head2 = mergeLists(lists, mid, end);
return merge(head1, head2);
};
return mergeLists(lists, 0, lists.length);
};
二叉树前序遍历
给你二叉树的根节点 root ,返回它节点值的 前序 遍历。
输入: root = [1,null,2,3]
输出: [1,2,3]
- 递归法
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
let arr = []
function qianxu(root){
if(!root||!root.val) return
arr.push(root.val)
qianxu(root.left)
qianxu(root.right)
}
qianxu(root)
return arr
};
- 迭代法
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number[]}
*/
var preorderTraversal = function(root) {
const stack = [];
const res = [];
if (root) stack.push(root);
while (stack.length) {
const node = stack.pop();
const left = node.left
const right = node.right
if (!node.left && !node.right) {
res.push(node.val);
continue;
}
if (right) stack.push(node.right); // 右
if (left) stack.push(node.left); // 左
node.left = null
node.right = null
stack.push(node); // 中
};
return res;
};