基本也都是看着别人的,经典的,自己敲一遍,做一下巩固,以后多看看,共勉
返回数组中重复最多的数字,重复了多少次
const arr = [1,3,5,8,9,3,2,5,6,5,3,1,2,2,3,3,4,4,3,3,3,3,7,0]
function searchMaxSame(arr=[]) {
if (!arr || !arr.length) return arr
let sameObj = {}
let maxCount = 0
let maxNum = 0
for (let i = 0; i < arr.length; i++) {
const item = arr[i]
if (!sameObj[item]) {
sameObj[item] = [item]
} else {
sameObj[item].push(item)
if (maxCount < sameObj[item].length) {
maxCount = sameObj[item].length
maxNum = item
}
}
}
return {
maxCount,
maxNum
}
}
console.log('searchMaxSame', searchMaxSame(arr.slice()))
在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
const matrix = [
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30],
];
function findNumIn2Darr(arr=[], target) {
if (!arr || !arr.length || !target) return false
for (let i = 0; i < arr.length; i++) {
const item = arr[i]
for (let j = 0; j < item.length; j++) {
console.log('item[j]', item[j])
if (item[j] === target) {
return true
}
}
}
return false
}
function findNumIn2Darr2(arr=[], target) {
if (!arr || !arr.length || !target) return false
let rows = arr.length
let columns = arr[0].length
let row = 0;
let column = columns - 1
while(row < rows && column >= 0) {
let item = arr[row][column]
if (target === item) {
return true
} else if (target > item) {
row++
} else {
column--
}
}
return false
}
console.log('findNumIn2Darr', findNumIn2Darr(matrix.slice(), 5))
console.log('findNumIn2Darr2', findNumIn2Darr2(matrix.slice(), 21))
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)
function reversePrint(head) {
if (!head) return head
const result = []
let node = head
while(node !== null) {
result.unshift(node.val)
node = node.next
}
return result
}
输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。
function TreeNode(val) {
this.val = val
this.left = this.right = null
}
function buildTree(preorder, inorder) {
if (!preorder.length) return
const rootVal = preorder[0]
const curNode = new TreeNode(rootVal)
const rootIndex = inorder.indexof(rootVal)
curNode.left = buildTree(preorder.slice(1, rootIndex + 1), inorder.slice(0, rootIndex))
curNode.right = buildTree(preorder.slice(rootIndex + 1), inorder.slice(rootIndex + 1))
return curNode
}
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
function CQueue(){
this.firstStack = []
this.secondStack = []
}
CQueue.prototype.appendTail = function(val) {
this.firstStack.push(val)
}
CQueue.prototype.deledeHead = function() {
if (this.secondStack.length) return this.secondStack.pop()
for (let i = 0; i < this.firstStack.length; i++) {
this.secondStack.push(this.firstStack.pop())
}
if (this.secondStack.length) {
return this.secondStack.pop()
} else {
return -1
}
}
写一个函数,输入 n ,求斐波那契(Fibonacci)数列的第 n 项(即 F(N))。斐波那契数列的定义如下, 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。
function fib(n) {
if (n <= 2) {
return 2
}
let p = 0, q = 0, r = 1
for (let i = 2; i < n; i++){
p = q
q = r
r = (p + q) % 1000000007
}
return r
}
青蛙跳,每次可跳1或2
function fib(n) {
let p = 0, q = 0, r = 1, k = 0
while(k < n) {
k++
p = q
q = r
r = (p + q) % 1000000007
}
return r
}
割绳子得最大数
function cuttingRope(n) {
if (n < 4) return n - 1
let a = Math.floor(n / 3)
let b = n % 3
switch(b) {
case 0:
return Math.pow(3, a)
case 1:
return Math.pow(3, a - 1) * 4
case 2:
return Math.pow(3, a) * 2
}
}
function cuttingRope(n){
if (n < 4) return n - 1
let res = 1
while(n > 4) {
n -= 3
res * 3
}
return res * num
}
计算二进制中1的数量
function numLen(n) {
return n.toString(2).split('0').join('').length
}
function getNumLen(n) {
return n.toString(2).match(/1/g).length || 0
}
手动实现 Math.pow
function myPow(x, n) {
if (n === 0) return 1
if (n < 0) return 1 / (x * myPow(x, -n - 1))
return n % 2 === 0 ? myPow(x, n / 2) : x * myPow(x, n - 1)
}
给定 n,返回n位数最大的数
function getMaxNum(n) {
let arr = []
let i = 0
while(arr.length <= n) {
i++
arr.push(i)
}
return {
maxNum: arr[arr.length - 1]
arr
}
}
给定数组,返回format后的数据
let arr = [
{id: 1, name: '部门1', pid: 0},
{id: 2, name: '部门2', pid: 1},
{id: 3, name: '部门3', pid: 1},
{id: 4, name: '部门4', pid: 3},
{id: 5, name: '部门5', pid: 4},
{id: 6, name: '部门5', pid: 2},
{id: 7, name: '部门5', pid: 4},
]
function arr2Tree(arr) {
let result = []
let map = {}
for (let item of arr) {
let { id, pid } = item
if (!map[id]) {
map[id] = {
...item,
children: []
}
}
const treeItem = map[id]
if (pid === 0) {
result.push(treeItem)
} else {
if (!map[pid]) {
map[pid] = {
children: []
}
}
map[pid].children.push(treeItem)
}
}
return result
}
给定一个列表表头,某节点val,删除这个节点
function deleteNode(head, val) {
if (head.val = val) return head.next
let prev = head
let next = prev.next
while(next) {
if (next.val === val) {
prev.next = next.next
break;
}
prev = next
next = next.next
}
return next
}
给定一个数组, 奇数在前,偶数在后
function reverseNum(arr) {
if (!arr || arr.length <= 1) return arr
let i = 0
ler newArr = []
while(i < arr.length) {
if (arr[i] % 2) {
newArr.unshift(arr[i])
} else {
newArr.push(arr[i])
}
i++
}
return newArr
}
function reverseNum(arr) {
if (!arr || arr.length <= 1) return arr
return arr.sort((a, b) => (b % 2) - (a % 2))
}
反转链表
function reverseLink(head) {
let prev = null
let cur = head
while(cur) {
const next = cur.next
cur.next = prev
prev = cur
cur = next
}
return prev
}
合并两个列表,要求从小到大排列
[2, 3, 4] [1, 2, 3] --> [1, 2, 2, 3, 3, 4]
function mergeTwoList(l1, l2) {
if (!l1) return l2
if (!l2) return l1
if (l1.val < l2.val) {
l1.next = mergeTwoList(l1.next, l2)
return l1
} else {
l2.next = mergeTwoList(l1, l2.next)
return l2
}
}
给定一个二叉树,判断另一个二叉树是否属于第一个
function isSubStrict(a, b) {
if (!a || !b) return false
return isSame(a, b) || isSubStrict(a.left, b) || isSubstrict(a.right, b)
}
function isSame(a, b) {
if (!b) return true
if (!a) return false
if (a.val !== b.val) return false
return isSame(a.left , b.lengt) && isSame(a.right, b.right)
}
给定一个二叉树,获取二叉树镜像
function TreeNode(head) {
this.val = head.val
this.left = null
this.right = null
}
function mirrorTree(head) {
if (!head) return null
let newTree = new TreeNode(head[0])
let left = head.left
let right = head.right
newTree.left = right
newTree.right = left
return newTree
}
判断二叉树是否是对称二叉树
function isSymmetric(root) {
return !root ? true : recur(root.left, root.right)
}
function recur(l, r) {
if (!l && !r) return true
if (!l || !r || l.val !== r.val) return false
return recur(l.left. r.right) && recur(l.right, r.left)
}
输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。
function spiralOrder(arr) {
if (!arr || !arr.length) return arr
let newArr = [], rows = arr.length, columns = arr[0].length, l = 0, t = 0, r = columns - 1, b = rows -1, size = rows * column;
while(newArr.length < size) {
for (let i = l; i <= r; i++) {
newArr.push(arr[t][i])
}
t++
for (let i = t; i <= b; i++) {
newArr.push(arr[i][r])
}
if (newArr.length === size) break;
r--
for (let i = r; i >= l; i--) {
newArr.push(arr[b][i])
}
b--
for (let i = b; i >= t; i--) {
newArr.push(arr[i][l])
}
l++
}
return newArr
}
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
function MinStack() {
this.stack = []
this.minStack = [Infinity]
}
MinStack.prototype.push = fucnt