斐波那次数列
斐波那契数列是指这样一个数列:1,1,2,3,5,8,13,21,34,55,89……这个数列从第3项开始 ,每一项都等于前两项之和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| function fibonacci(n){ if (n < 2) { return; } let tmp1 = 1; let tmp2 = 1; let tmp3; for (var i = 1; i < n; i++) { tmp3 = tmp1 + tmp2; tmp1 = tmp2; tmp2 = tmp3; } return tmp3; } console.log(fibonacci(9))
|
快速排序
采用“分治”的思想,对于一组数据,选择一个基准元素(base),通常选择第一个或最后一个元素,通过第一轮扫描,比base小的元素都在base左边,比base大的元素都在base右边,再有同样的方法递归排序这两部分,直到序列中所有数据均有序为止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| function quickSort(arr) { function swap(arr, a, b) { console.log('swap ' + arr[a] + ' ' + arr[b]) var temp = arr[a]; arr[a] = arr[b]; arr[b] = temp; }
function partition(arr, left, right) {
var pivot = arr[right];
var storeIndex = left; for (var i = left; i < right; i++) { if (arr[i] < pivot) {
swap(arr, storeIndex, i); storeIndex++; } } swap(arr, right, storeIndex);
console.log('storeIndex ' + storeIndex) return storeIndex; }
function sort(arr, left, right) { if (left > right) return;
var storeIndex = partition(arr, left, right); sort(arr, left, storeIndex - 1); sort(arr, storeIndex + 1, right); }
sort(arr, 0, arr.length - 1); return arr; }
|
二叉树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| class Node { constructor(key) { this.key = key; this.left = null; this.right = null; } } class BinarySearchTree { constructor(keys) { this.root = null; keys.forEach((key) => { let newNode = new Node(key) if (this.root === null) { this.root = newNode } else { this.insertNode(this.root, newNode) } }) } insertNode(node, newNode) { if (newNode.key < node.key) { if (node.left === null) { node.left = newNode } else { this.insertNode(node.left, newNode) } } else { if (node.right === null) { node.right = newNode } else { this.insertNode(node.right, newNode) } } } traverse(node, order, callback) { if (node !== null) { order === 'root-left-right' && callback(node.key); this.traverse(node.left, order, callback) order === 'left-root-right' && callback(node.key); this.traverse(node.right, order, callback) order === 'left-right-root' && callback(node.key); } } findMin () { let node = this.root; while (node.left) { node = node.left; } return node.key; } findMax () { let node = this.root; while (node.right) { node = node.right; } return node.key; } }
const keys = [8, 3, 10, 1, 6, 14, 4, 7, 13]; const tree = new BinarySearchTree(keys); tree.traverse(tree.root, 'left-right-root', (key) => { console.log(key); }); console.log('————'); console.log('findMin: ' + tree.findMin()); console.log('findMax: ' + tree.findMax());
|
微信红包算法
- 所有人抢到金额之和等于红包总金额,不能超过,也不能少于;
- 抢到的红包金额至少是一分钱;
- 要保证抢到红包的人获取到的红包金额是随机的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| const MIN_AMOUNT = 2; const MAX_AMOUNT = 40; const luckyPackages = (num, total) => { const result = new Array(num); result.fill(MIN_AMOUNT); let remainder = total - (num * MIN_AMOUNT); while(remainder > 0) { const ran = Math.random(); const i = Math.floor(num * ran); const split = remainder < 1 ? remainder : Number(((remainder/4) * ran).toFixed(1));
if ((result[i] + split) <= MAX_AMOUNT) { result[i] += split; remainder -= split; } else { remainder -= MAX_AMOUNT - result[i]; result[i] = MAX_AMOUNT; } } result.forEach((n, i) => { result[i] = Number(n.toFixed(1)) }); console.log(result.reduce((total, num) => { return total + Number(num); }, 0)) console.log(result.join(', ')); }; luckyPackages(20, 200);
|
js 实现两个字符串数字相加(大数相加)
我面试抖音的面试题,中等难度
1 2 3 4 5 6 7 8 9 10 11
| const addStr = (num1, num2) => { const len = Math.max(num1.length, num2.length); const str1 = num1.padStart(len, '0') const str2 = num2.padStart(len, '0') const result = []; for (let i = len - 1; i >= 0; i--) { result.push(parseInt(str1[i] || 0) + parseInt(str2[i] || 0)); } return result.reverse().join(''); }; console.log(addStr('123454321', '456'))
|
八皇后问题
八皇后问题,是一个古老而著名的问题,是 回溯算法 的典型案例。
该问题是国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
使用回溯算法,高斯认为有 76 种方案。1854年在柏林的象棋杂志上不同的作者发表了 40 种不同的解,后来有人用图论的方法解出 92 种结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function hasConflict(row, column, queens) { return queens.some(a => a[0] === row) || queens.some(a => a[1] === column) || queens.some(a => Math.abs(a[0] - row) === Math.abs(a[1] - column)); } function printQ(queens){ const str = Array.from({ length: 8 }, () => Array(8).fill('-')); queens.forEach(a => { str[a[0]][a[1]] = 'Q'; }) console.log(str.map(a => a.join(' ')).join('\n')) } let count = 0; function find_queen(row, queens) { if (row === 8) { count++; console.log('Eight Queens Solve ' +count) printQ(queens); return; } for(let column = 0; column < 8; column++) { if (!hasConflict(row, column, queens)) { queens.push([row, column]); find_queen(row+1, queens); queens.pop(); } } } find_queen(0, []);
|
爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const cache = {}; const climbStairs = (n) => { if (n === 1) { return 1; } if (n === 2) { return 2; } if (n === 3) { return 3; } if (cache[n]) { return cache[n]; } const a = climbStairs(n - 1) const b = climbStairs(n - 2); cache[n] = a + b; return a + b; } console.log( climbStairs(46))
|
移动零
使用双指针,j指针填充的位置,遇到0停下,然后填充i指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const moveZeroes = (nums) => { let j = 0; for(let i=0;i<nums.length;++i) { if(nums[i]!=0) { nums[j++] = nums[i]; console.log(nums.join(' ')) } } for(let i=j;i<nums.length;++i) { nums[i] = 0; } return nums; } console.log(moveZeroes([0,1,0,3,12]))
|