// 求中位数
function test(arr) {arr.sort((a, b) => a - b);if (arr.length % 2 === 0) {return (arr[arr.length / 2 -1] + arr[arr.length / 2]) / 2} else {return arr[Math.floor(arr.length / 2)]}
}
test([2,3,4]);// 二分法
function test(arr, target) {let left = 0;let right = arr.length;while(left <= right) {let mid = left + Math.floor((right - left) / 2);if (arr[mid] < target) {left = mid + 1;} else {right = mid -1;}}return right + 1;
}
console.log(test([2,5,7,9,20], 9.5))// 先序中序后序递归遍历一个树
function treeRecurse(tree) {if (!tree) return;console.log(tree.element);treeRecurse(tree.left);treeRecurse(tree.right);
}
function treeRecurse(tree) {if (!tree) return;treeRecurse(tree.left);console.log(tree.element);treeRecurse(tree.right);
}
function treeRecurse(tree) {if (!tree) return;treeRecurse(tree.left);treeRecurse(tree.right);console.log(tree.element);console.log(tree.element);
}// 写一个简单树类Tree,包含add, insert
class Node {constructor(element) {this.element = element;this.left = null;this.right = null;}
}class Tree {constructor() {this.root = null;}insert(root, node) {if (root.element < node) {if (!root.left) {root.left = node;} else {this.insert(root.left, node)}} else {if (!root.right) {root.right = node;} else {this.insert(root.right, node)}}}add (data) {const node = new Node(data);if (this.root === null) {this.root = node;} else {this.insert(this.root, node)}}
}const t = new Tree();
t.add(2);
t.add(4);
t.add(9);// 写一个简单链表类LinkList,包含insert, append方法
class Node {constructor(element) {this.element = element;this.next = null;}
}class LinkList {constructor(){this.head = null;this.length = 0;}insert(position, element) {let node = new Node(element);if(!this.head){this.head = node;} else {let index = 0;let current = this.head;let previous = null;while(index++ < position){ // 找到要在谁之前插入那一项previous = current; // 那到要插入到哪项之前current = current.next; // 插入到前一个后面}previous.next = node;node.next = current;}}append(l){const newNode = new Node(l);if (!this.head) {this.head = newNode;} else {let index = 0;let current = this.head;while(++index < this.length) {current = current.next;}current.next = node;}}
}const l = new LinkList();
l.append(2);
l.append(4);
l.append(8);// 一个简单的数据结构Set
class Set {constructor() {this.cache = {};}add(element) {this.cache[element] = element;}
}// 写一个Map类,包含set,get,calc
class Map {constructor() {this.map = [];}calc(key) {let total = 0;for(let i=0;i<key.length;i++) {total += key[i].charCodeAt();}return total % 100;}set(key, element) {this.cache[this.calc(key)] = element;}get(key) {return this.cache[this.calc(key)];}
}// 快速排序
function test(arr) {if (arr.length < 2) {return arr;}const target = arr[0];const left = [];const right = [];for (let i = 1; i< arr.length; i++) {if (arr[i] < target) {left.push((arr[i]))}if (arr[i] > target) {right.push((arr[i]));}}return test(left).concat([target], test(right));
}
console.log(test([3,23,13,90,45]));// 递归node dfs 深度优先
let dfs = (node, result = []) => {if (node !== null) {result.push(node)node.children && node.children.forEach(item => {dfs(children[i], result)})}return result
}
// 递归tree dfs 深度优先
function dfsTree(tree, result = []) {if (tree) {dfsTree(tree.left, result)result.push(tree, result)dfsTree(tree.right, result)}
}
// dfs 非递归
function dfsTree2(tree, result = []) {const stack = [];if (tree) {stack.push(tree)while (stack.length) {const item = stack.pop();result.push(item);const children = [stack.left, stack.right].filter(w => w);children.forEach(i => {stack.push(i);})}}
}// bfs
function bfs(tree, result = []) {const stack = [];if (tree) {stack.push(tree)while (stack.length) {const item = stack.shift();result.push(item);const children = [item.left, item.right].filter(w => w);children.forEach(i => {stack.push(i);})}}
}
二叉树的最大深度
function TreeDepth(pRoot) {return !pRoot ? 0 : (Math.max(TreeDepth(pRoot.left), TreeDepth(pRoot.right)) + 1)
}
二叉树的最小深度
var minDepth = function (root) {if (!root) {return 0;}if (!root.left) {return 1 + minDepth(root.right);}if (!root.right) {return 1 + minDepth(root.left);}return Math.min(minDepth(root.left), minDepth(root.right)) + 1
};
url 切割
// 方法一
var url = 'https://www.baidu.com/a/b?name=王小二&age=8&hobby=敲代码&hobby=soccer';
function fn(str) {let obj = {};var arr = str.split('?')[1].split('&');arr.forEach(item => {const key = item.split('=')[0];const value = item.split('=')[1];if (!obj[key]) {obj[key] = value;} else {obj[key] = [].concat(obj[key], value);}})return obj;
}
console.log(fn(url));
// 方法2
let str = 'sadf?key=14&key=24&key=34&test=44';
let result = {};
str.replace(/([^?=&]+)=([^&=]+)/g, function () {// console.log(arguments[0], arguments[1], arguments[2])// key=14 key 14if (!result[arguments[1]]) {result[arguments[1]] = arguments[2];} else {result[arguments[1]] = [].concat(result[arguments[1]], arguments[2])}
});字符串每三位加一个逗号
---方法1:
// JS 自带的 toLocaleString
function formatNumber(num) {return Number(num).toLocaleString()
}
---方法2:
// 正则表达式
function formatNumber(num) {return num.toString().replace(/\d+/, function (n) {return n.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')})
}
console.log(formatNumber(123456789.123)) // 123,456,789.123
---方法4:
// slice 截取分割
function formatNumber(num, char=',', length=3) {let result = ''let nums = num.toString().split('.')let int = nums[0];let decmial = nums[1] ? '.' + nums[1] : ''while (int.length > length) {result = char + int.slice(-length) + resultint = int.slice(0, int.length - length)}if (int) { result = int + result }return result + decmial
}
console.log(formatNumber(123456789.123)) // 123,456,789.123
---反转字符串
var reverseString = function(s) {const n = s.length;for (let left = 0, right = n - 1; left < right; ++left, --right) {[s[left], s[right]] = [s[right], s[left]];}
}
---比较版本
function compare( version1 ,  version2 ) {let arr1=version1.split(".");let arr2=version2.split(".");let length=Math.max(arr1.length,arr2.length);for (let i = 0; i < length; i++) {const n1 = Number(arr1[i]||0)const n2 = Number(arr2[i]||0)if (n1 > n2) return 1if (n1 < n2) return -1}return 0
}
---两数之和
var twoSum = function(nums, target) {const map = new Map();for(let i = 0, len = nums.length;i < len;i++) {if(map.has(target - nums[i])) {return [map.get(target - nums[i]), i];}map.set(nums[i], i);}return [];
};
---三数之和为0
---方法2 排序 + 双指针
时间复杂度:O(N^2)  时间复杂度O(N)
var threeSum = function(nums) {let arr = []// 直接sort()是根据字母、数字大小排序,导致-1排在-3左边nums.sort((a,b) => a-b)for (let i = 0; i < nums.length-2; i++) {// 当遍历下一个target与前面的相同时,跳过if (i > 0 && nums[i] == nums[i-1]) continue let target = nums[i], x = i + 1, y = nums.length - 1 while (x < y) {let sum = target + nums[x] + nums[y]if (sum == 0) {arr.push([target, nums[x], nums[y]])// 准备夹逼前,将左右俩边移到相同数值最紧处while (x < y && nums[x+1] == nums[x]) x++while (x < y && nums[y-1] == nums[y]) y--// 有了上述的准备过程,这里夹逼时,左右俩边数值与上次数值不同x++y--} else if (sum > 0) {y--} else {x++}}}return arr
};
---在排序数组中查找元素的第一个和最后一个位置
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
----答案
const binarySearch = (nums, target, lower) => {let left = 0, right = nums.length - 1, ans = nums.length;while (left <= right) {const mid = Math.floor((left + right) / 2);if (nums[mid] > target || (lower && nums[mid] >= target)) {right = mid - 1;ans = mid;} else {left = mid + 1;}}return ans;
}
var searchRange = function(nums, target) {let ans = [-1, -1];const leftIdx = binarySearch(nums, target, true);const rightIdx = binarySearch(nums, target, false) - 1;if (leftIdx <= rightIdx && rightIdx < nums.length && nums[leftIdx] === target && nums[rightIdx] === target) {ans = [leftIdx, rightIdx];} return ans;
};
合并两个有序数组
1. 直接合并然后排序
时间复杂度:(m+n)log(m+n)
空间复杂度:log(m+n)
2. 双指针
时间复杂度:O(m+n)
空间复杂度:O(m+n)
var merge = function(nums1, m, nums2, n) {let p1 = 0, p2 = 0;const sorted = new Array(m + n).fill(0);var cur;while (p1 < m || p2 < n) {if (p1 === m) {cur = nums2[p2++];} else if (p2 === n) {cur = nums1[p1++];} else if (nums1[p1] < nums2[p2]) {cur = nums1[p1++];} else {cur = nums2[p2++];}sorted[p1 + p2 - 1] = cur;}for (let i = 0; i != m + n; ++i) {nums1[i] = sorted[i];}
};
寻找两个正序数组的中位数
----方法1.合并数组
----方法2:方法二:划分数组(太复杂,不建议背诵)

数组

// 数组中存在两数之和为target,并且返回两数的下标
// 输入:nums = [3,2,4], target = 6
// 输出:[1,2]
function twoNum (nums, target) {const map = Map();for(let i; i<nums.length; i++) {if (map.has(target - nums[i])){return [ map.get(nums[i]), nums[i]];} else {map.set(nums[i], i);}}
}
// 三数之和
// ---方法2 排序 + 双指针
// 时间复杂度:O(N^2)  空间复杂度O(N)
var threeSum = function (nums, flag) {let arr = []// 直接sort()是根据字母、数字大小排序,导致-1排在-3左边nums.sort((a, b) => a - b)for (let i = 0; i < nums.length - 2; i++) {// 当遍历下一个target与前面的相同时,跳过if (i > 0 && nums[i] == nums[i - 1]) continuelet target = nums[i], x = i + 1, y = nums.length - 1while (x < y) {let sum = target + nums[x] + nums[y]if (sum == flag) {arr.push([target, nums[x], nums[y]])// 准备夹逼前,将左右俩边移到相同数值最紧处// 这里的两句其实不用看,用来处理重复的时候,一般测试用例不会重复// while (x < y && nums[x + 1] == nums[x]) x++// while (x < y && nums[y - 1] == nums[y]) y--// 有了上述的准备过程,这里夹逼时,左右俩边数值与上次数值不同x++y--} else if (sum > flag) {y--} else {x++}}}return arr
};// 数组反转
var reverseString = function(s) {const n = s.length;for (let left = 0, right = n - 1; left < right; ++left, --right) {[s[left], s[right]] = [s[right], s[left]];}
}
reverseString([2, 3, 10, 20])// 合并两个有序数组
// ----方法1 方法一:直接合并后排序
// 时间复杂度:(m+n)log(m+n)
// 空间复杂度:log(m+n)
var merge = function(nums1, m, nums2, n) {nums1.splice(m, nums1.length - m, ...nums2);nums1.sort((a, b) => a - b);
};
// 方法二:双指针
var merge = function(nums1, m, nums2, n) {let p1 = 0, p2 = 0;const sorted = new Array(m + n).fill(0);var cur;while (p1 < m || p2 < n) {if (p1 === m) {cur = nums2[p2++];} else if (p2 === n) {cur = nums1[p1++];} else if (nums1[p1] < nums2[p2]) {cur = nums1[p1++];} else {cur = nums2[p2++];}sorted[p1 + p2 - 1] = cur;}for (let i = 0; i != m + n; ++i) {nums1[i] = sorted[i];}
};// 寻找两个正序数组的中位数
var findMedianSortedArrays = (nums1, nums2) => {let len1 = nums1.length, len2 = nums2.lengthif (len1 > len2) return findMedianSortedArrays(nums2, nums1)//对nums1和nums2中长度较小的二分let len = len1 + len2//总长let start = 0, end = len1 //进行二分的开始和结束位置let partLen1, partLen2while (start <= end) {partLen1 = (start + end) >> 1 // nums1二分的位置partLen2 = ((len + 1) >> 1) - partLen1 //nums2二分的位置// L1:nums1二分之后左侧的结束位置,R1 nums1二分之后右侧的起始位置// L2,nums2二分之后左侧结束的位置,R2 nums2二分之后右侧的起始位置//如果左边没字符了,就定义成-Infinity,让所有数都大于它,否则就是nums1二分的位置左边一个let L1 = partLen1 === 0 ? -Infinity : nums1[partLen1 - 1]//如果左边没字符了,就定义成-Infinity,让所有数都大于它,否则就是nums2二分的位置左边一个let L2 = partLen2 === 0 ? -Infinity : nums2[partLen2 - 1]//如果右边没字符了,就定义成Infinity,让所有数都小于它,否则就是nums1二分的位置let R1 = partLen1 === len1 ? Infinity : nums1[partLen1]//如果右边没字符了,就定义成Infinity,让所有数都小于它,否则就是nums1二分的位置let R2 = partLen2 === len2 ? Infinity : nums2[partLen2]if (L1 > R2) {//不符合交叉小于等于 继续二分end = partLen1 - 1} else if (L2 > R1) {//不符合交叉小于等于 继续二分start = partLen1 + 1} else { // L1 <= R2 && L2 <= R1 符合交叉小于等于return len % 2 === 0 ?(Math.max(L1, L2) + Math.min(R1, R2)) / 2 : //长度为偶数返回作左侧较大者和右边较小者和的一半Math.max(L1, L2)    //长度为奇数返回作左侧较大者}}
}// 两个数组的交集
// 方法1:两个集合
var intersection = function (arr1, arr2) {const set1 = new Set(arr1);const set2 = new Set(arr2);return handle(set1, set2);
};
function handle(set1, set2) {if (set1.size > set2.size) {return handle(set2, set1)}let result = new Set();for (let item of set1) {if (set2.has(item)) {result.add(item);}}return [...result];
}
// 方法2:排序 + 双指针
var intersection = function(nums1, nums2) {nums1.sort((x, y) => x - y);nums2.sort((x, y) => x - y);const length1 = nums1.length, length2 = nums2.length;let index1 = 0, index2 = 0;const intersection = [];while (index1 < length1 && index2 < length2) {const num1 = nums1[index1], num2 = nums2[index2];if (num1 === num2) {// 保证加入元素的唯一性if (!intersection.length || num1 !== intersection[intersection.length - 1]) {intersection.push(num1);}index1++;index2++;} else if (num1 < num2) {index1++;} else {index2++;}}return intersection;
};// 在排序数组中查找元素的第一个和最后一个位置
var searchRange = function(nums, target) {let left = 0;let right = nums.length - 1; // 定义target在左闭右闭的区间里,[left, right]while(left<=right){while(left<right&&nums[left]<target){left++;}while(left<right&&nums[right]>target){right--;}if(nums[left] == target&&nums[right]==target){return [left,right];}else{break;}}return [-1, -1];
};

----打印

-------------函数科利华 curring
const curring = (fn,arr = [])=>{let len = fn.lengthreturn (...args)=>{arr = arr.concat(args);if(arr.length < len){return curring(fn,arr)}return fn(...arr)}
}
-------------订阅模式
class EventEmitTest {constructor() {this.cache = {};}on(type, fn) {if (!this.cache[type]) {this.cache[type] = [];}this.cache[type].push(fn);}emit(type) {this.cache[type].forEach(item => item.call(item, arguments));}
}
------------js处理扁平数组和树结构相互转换
function toTree(data) {const obj = {};data.forEach(item => {obj[item.id] = item; })const result = [];data.forEach((item) => {const parent = obj[item.parentId];if (parent) {parent.children = parent.children || [];parent.children.push(item);} else {result.push(item)}})return result;
}
-------------深度克隆 deepCopy
function deepCopy(value, hash = new WeakMap){if(!value || typeof value !== 'object')return value;if (hash.has(value)) {return hash.get(value)}let newObject = Array.isArray(value) ? [] : {};hasn.set(value, newObject);//遍历对象中的key Object.keys 对数组一样可以用Object.keys(value).forEach(key => {newObject[key] = value[key];})return newObject;
}
-------------reduce
function reduceTest(fn, init) {let result;this.forEach((item, itemIndex) => {if (itemIndex === 0) {if (init) {result = fn(init, item, itemIndex)} else {result = item;}} else {result = fn(result, item, itemIndex);}});return result;
}
-------------compose
function compose(...args) {return function (...params) {const fn = args.pop();const first = fn(...params);return args.reduceRight((prev, item) => {return item(prev)}, first)}
}
-------------create 的原理
function create(parentProto,{constructor: Tiger}){function Fn(){}Fn.prototype = parentProto;let fn = new Fn();fn.constructor = Tigerreturn fn;
}
-------------new 的原理
function mockNew(A){let obj = {}let returnVal = A.call(obj);if (result instanceof Object) {return returnVal;}obj.__proto__ = A.prototypereturn obj;
}
-------------浅冻结和深冻结
function deepFreeze(obj){Object.keys(obj).forEach(item => {if (typeof item === 'object' && item !== null){deepFreeze(item)}})return Object.freeze(obj);
}
-------------数组的扁平化处理mockFlat
function mockFlat(arr, depth = 1){if (depth <=0) {return arr;}let res = [];arr.forEach(item => {if(Array.isArray(item)){res = res.concat(mockFlat(item));}else{res.push(item);}});depth--;return res;
}
------------instanceof
function newInstanceof(leftVaule, rightVaule) { let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值while (true) {if (leftVaule === null) {return false;  }if (leftVaule === rightProto) {return true;  } leftVaule = leftVaule.__proto__ }
}
-------------mock bind
Function.prototype.mockbind = function() {const [ctx, ...args] = arguments;// this为真正执行的函数const fun = this;function result (...args2) {// 考虑是否是构造ctx = this instanceof result ? this : ctx;fun.apply(ctx, args.concat(args2));}result.prototype = Object.create(fun.prototype);return result;
}
-------------call apply
function newCall() {let [ctx, ...args] = arguments;if (!ctx) {ctx = window;}ctx.func = this;let result = ctx.func(...args);delete ctx.func; // 为什么赋值后在删除,因为函数执行后的this指向函数作用域return result;
}
function newApply() {let [ctx, args] = arguments;if (!ctx) {ctx = window;}ctx.func = this;let result;// 这里因为args可能为undefined无法通过...运算符,所以必须区分if (args) {result = ctx.func(...args);} else {result = ctx.func();}delete result.func;return result;
}
-------------自己实现 UseState useEffect
const memoState = [];
const cursor = 0;
function mockUseState(initval) {state[cursor] = state[cursor] || initval;function setState(data) {state[cursor] = data;render();}return [state[cursor++], setState];
}
function mockUseEffect(render, deps) {const cacheDeps = state[cursor];const same = cacheDeps ? cacheDeps.every((item, itemIndex) => item === deps[itemIndex]) : false;if (!same) {render();state[cursor] = deps;}cursor++;
}
-------------useMemo
function mockUseMemo(render, deps) {if (state[cursor]) {const [cacheData, cacheDeps] = state[cursor];const same =  cacheDeps ? cacheDeps.every((item, itemIndex) => item === deps[itemIndex]) : false;if (same) {return cacheData;}}const data = render();// 第一次渲染 或者 不是第一次但是依赖项相同,都返回新的state[cursor++] = [data, deps];return data;
}
-------------useCallback
function mockUseCallback(render, deps){if (state[cursor]) {const [cacheRender, cacheDeps] = state[cursor];const same =  cacheDeps ? cacheDeps.every((item, itemIndex) => item === deps[itemIndex]) : false;if (same) {return cacheRender;}}// 第一次渲染 或者 不是第一次但是依赖项相同,都返回新的state[cursor++] = [render, deps];return render;
}
-------------求中位数
let _median = arr => {arr.sort((a, b) => {if (a < b) return -1;if (a > b) return 1;return 0;})//求中位数if (arr.length % 2 == 0) {return (arr[arr.length / 2 - 1] + arr[arr.length / 2]) / 2;} else {return arr[Math.floor(arr.length / 2)];}
};
-------------二分查找
var search = function(nums, target) {// right是数组最后一个数的下标,num[right]在查找范围内,是左闭右闭区间let left = 0, right = nums.length - 1;// 当left=right时,由于nums[right]在查找范围内,所以要包括此情况while (left <= right) {let mid = left + Math.floor((right - left)/2);// 如果中间数大于目标值,要把中间数排除查找范围,所以右边界更新为mid-1;如果右边界更新为mid,那中间数还在下次查找范围内if (nums[mid] > target) {right = mid - 1;  // 去左面闭区间寻找} else if (nums[mid] < target) {left = mid + 1;   // 去右面闭区间寻找} else {return mid;}}return -1;
};
-------------快速排序两数组实现
function quickSort(array) {if (array.length < 2) {return array;}const target = array[0];const left = [];const right = [];for (let i = 1; i < array.length; i++) {if (array[i] < target) {left.push(array[i]);} else {right.push(array[i]);}}return quickSort(left).concat([target], quickSort(right));
}
-------------两数之和
var twoSum = function(nums, target) {const map = new Map();for(let i = 0, len = nums.length;i < len;i++) {if(map.has(target - nums[i])) {return [map.get(target - nums[i]), i];}map.set(nums[i], i);}return [];
}
------------链表 快慢指针
var middleNode = function(head) {slow = fast = head;while (fast && fast.next) {slow = slow.next;fast = fast.next.next;}return slow;
};
------------数组反转
var reverseString = function(s) {const n = s.length;for (let left = 0, right = n - 1; left < right; ++left, --right) {[s[left], s[right]] = [s[right], s[left]];}
}
------------url 切割
function fn(str) {let obj = {};var arr = str.split('?')[1].split('&');arr.forEach(item => {const key = item.split('=')[0];const value = item.split('=')[1];if (!obj[key]) {obj[key] = value;} else {obj[key] = [].concat(obj[key], value);}})return obj;
}
-----方法2
let result = {};
str.replace(/([^?=&]+)=([^&=]+)/g, function () {// console.log(arguments[0], arguments[1], arguments[2])// key=14 key 14if (!result[arguments[1]]) {result[arguments[1]] = arguments[2];} else {result[arguments[1]] = [].concat(result[arguments[1]], arguments[2])}
});
------------字符串每三位加一个逗号
function formatNumber(num) {return Number(num).toLocaleString()
}
---方法2
function formatNumber(num) {return num.toString().replace(/\d+/, function (n) {return n.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')})
}
------------版本比较
function compare( version1 ,  version2 ) {let arr1=version1.split(".");let arr2=version2.split(".");let length=Math.max(arr1.length,arr2.length);for (let i = 0; i < length; i++) {const n1 = Number(arr1[i]||0)const n2 = Number(arr2[i]||0)if (n1 > n2) return 1if (n1 < n2) return -1}return 0
}
------------
数组
------------合并两个有序数组
方法二:双指针
时间复杂度:O(m+n)
空间复杂度:O(m+n)
var merge = function(nums1, m, nums2, n) {let p1 = 0, p2 = 0;const sorted = new Array(m + n).fill(0);var cur;while (p1 < m || p2 < n) {if (p1 === m) {cur = nums2[p2++];} else if (p2 === n) {cur = nums1[p1++];} else if (nums1[p1] < nums2[p2]) {cur = nums1[p1++];} else {cur = nums2[p2++];}sorted[p1 + p2 - 1] = cur;}for (let i = 0; i != m + n; ++i) {nums1[i] = sorted[i];}
};
------------两个数组的交集
时间复杂度 O(mlogm+nlogn)
空间复杂度 O(logm+logn)
var intersection = function(nums1, nums2) {nums1.sort((x, y) => x - y);nums2.sort((x, y) => x - y);const length1 = nums1.length, length2 = nums2.length;let index1 = 0, index2 = 0;const intersection = [];while (index1 < length1 && index2 < length2) {const num1 = nums1[index1], num2 = nums2[index2];if (num1 === num2) {// 保证加入元素的唯一性if (!intersection.length || num1 !== intersection[intersection.length - 1]) {intersection.push(num1);}index1++;index2++;} else if (num1 < num2) {index1++;} else {index2++;}}return intersection;
};
------------寻找两个正序数组的中位数
var findMedianSortedArrays = (nums1, nums2) => {let len1 = nums1.length, len2 = nums2.lengthif (len1 > len2) return findMedianSortedArrays(nums2, nums1)//对nums1和nums2中长度较小的二分let len = len1 + len2//总长let start = 0, end = len1 //进行二分的开始和结束位置let partLen1, partLen2while (start <= end) {partLen1 = (start + end) >> 1 // nums1二分的位置partLen2 = ((len + 1) >> 1) - partLen1 //nums2二分的位置// L1:nums1二分之后左侧的结束位置,R1 nums1二分之后右侧的起始位置// L2,nums2二分之后左侧结束的位置,R2 nums2二分之后右侧的起始位置  //如果左边没字符了,就定义成-Infinity,让所有数都大于它,否则就是nums1二分的位置左边一个let L1 = partLen1 === 0 ? -Infinity : nums1[partLen1 - 1]//如果左边没字符了,就定义成-Infinity,让所有数都大于它,否则就是nums2二分的位置左边一个let L2 = partLen2 === 0 ? -Infinity : nums2[partLen2 - 1]//如果右边没字符了,就定义成Infinity,让所有数都小于它,否则就是nums1二分的位置let R1 = partLen1 === len1 ? Infinity : nums1[partLen1]//如果右边没字符了,就定义成Infinity,让所有数都小于它,否则就是nums1二分的位置let R2 = partLen2 === len2 ? Infinity : nums2[partLen2]if (L1 > R2) {//不符合交叉小于等于 继续二分end = partLen1 - 1} else if (L2 > R1) {//不符合交叉小于等于 继续二分start = partLen1 + 1} else { // L1 <= R2 && L2 <= R1 符合交叉小于等于return len % 2 === 0 ?(Math.max(L1, L2) + Math.min(R1, R2)) / 2 : //长度为偶数返回作左侧较大者和右边较小者和的一半Math.max(L1, L2)  //长度为奇数返回作左侧较大者}}
}
------
二叉搜索树学习
------------二叉树的最大深度
function TreeDepth(pRoot) {return !pRoot ? 0 : (Math.max(TreeDepth(pRoot.left), TreeDepth(pRoot.right)) + 1)}------------二叉树的最小深度var minDepth = function (root) {if (!root) {return 0;}if (!root.left) {return 1 + minDepth(root.right);}if (!root.right) {return 1 + minDepth(root.left);}return Math.min(minDepth(root.left), minDepth(root.right)) + 1
};
------------二叉搜索树中的搜索
var searchBST = function(root, val) {if (!root || val===undefined) return null;if (root.val === val) return root;return root.val > val ? searchBST(root.left, val) : searchBST(root.right, val);
};
-----------二叉树展开为链表
var flatten = function(root) {const list = [];preorderTraversal(root, list);const size = list.length;for (let i = 1; i < size; i++) {// 这里利用了每一项curr其实还是一个tree node含有left,rightconst prev = list[i - 1], curr = list[i];prev.left = null;prev.right = curr;}
};const preorderTraversal = (root, list) => {if (root != null) {list.push(root);preorderTraversal(root.left, list);preorderTraversal(root.right, list);}
}
-----------二叉搜索树中两个节点之和
var findTarget = function(root, k) {const set = new Set();const helper = (root, k) => {if (!root) {return false;}if (set.has(k - root.val)) {return true;}set.add(root.val);return helper(root.left, k) || helper(root.right, k);}return helper(root, k);
};
-----------将有序数组转换为二叉搜索树
function TreeNode(val) {this.val = val;this.left = this.right = null;
}function toTreeNode(arr, left, right) {let mid = Math.floor((right + left) / 2);let node = new TreeNode(arr[mid]);if (left === right) return node;node.right = toTreeNode(arr, mid + 1, right);if (right - left === 1) return node;node.left = toTreeNode(arr, left, mid - 1);return node;
}
var sortedArrayToBST = function(nums) {if (nums.length === 0) {return null}return toTreeNode(nums, 0, nums.length - 1);
};
-----------验证二叉搜索树
const helper = (root, lower, upper) => {if (root === null) {return true;}if (root.val <= lower || root.val >= upper) {return false;}return helper(root.left, lower, root.val) && helper(root.right, root.val, upper);
}
var isValidBST = function(root) {return helper(root, -Infinity, Infinity);
};
------------路径总和
var hasPathSum = function(root, targetSum) {if(!root) {return false;}if(!root.left && !root.right) {return targetSum === root.val;}return hasPathSum(root.left, targetSum - root.val) || hasPathSum(root.right, targetSum - root.val);
};
----------
其他算法
----------LRU 缓存
var LRUCache = function(capacity) {this.map = new Map()this.capacity = capacity
};
LRUCache.prototype.get = function(key) {if(this.map.has(key)){let value = this.map.get(key)this.map.delete(key)this.map.set(key, value)return value}return -1
};
LRUCache.prototype.put = function(key, value) {if (this.map.has(key)) {this.map.delete(key) }this.map.set(key, value)if(this.map.size > this.capacity){this.map.delete(this.map.keys().next().value)}
};
----------KMP算法

算法点滴yan测试+打印相关推荐

  1. 测试打印 lua 的 _G 所有显示的字段内容

    -- jave.lin - tiny_testing.lua - 测试打印 lua 的 _G--[=[local bit = require("bit")--local band, ...

  2. webpack点滴yan

    分为webpack优化 webpack基础 https://blog.csdn.net/weixin_42201346/article/details/105102503 webpack原理实现 ht ...

  3. 国密SM9算法C++实现之九:算法功能与测试例子

    SM9算法C++实现系列目录: 基于JPBC的SM9算法的java实现与测试 国密SM9算法C++实现之0:源码下载地址 国密SM9算法C++实现之一:算法简介 国密SM9算法C++实现之二:测试工具 ...

  4. 3d打印机 测试打印stl_如何进行3D打印(即使您没有3D打印机也是如此)

    3d打印机 测试打印stl 3D printers are amazing tools that let you make almost any kind of physical object you ...

  5. JAVA调用Bartender进行标签打印(可本地用打印机客户端进行测试打印,【云上的项目】可通过WebSocket进行通讯进行打印)

    用Java编写一个打印标签客户端 点击运行启动会打开首页 可以点击预览打印 点击打印可测试成功 打印机结果 前端用的是thymeleaf 代码片段 <!DOCTYPE html> < ...

  6. 算法学习之路|打印排名

    上机考试虽然有实时的Ranklist,但上面的排名只是根据完成的题数排序,没有考虑 每题的分值,所以并不是最后的排名.给定录取分线,请你写程序找出最后通过分数线的 考生,并将他们的成绩按降序打印. 输 ...

  7. 浏览器渲染点滴yan

    打印: 在浏览器地址栏输入URL,按下回车后究竟发生了什么? DOMContentLoaded与load的区别.触发时机 浏览器连接限制 defer async 针对script标签 preload, ...

  8. 基于PP-OCR的文字识别算法移植与测试

    课程全程将在SOPHGO(算能)云平台上进行. 本次课程将介绍: 1. SOPHGO(算能)云平台环境搭建 2. PP-OCR的文字识别算法 3. 通过BMNNSDK进行PP-OCR模型转换和量化 4 ...

  9. 算法效果AB测试中的PV-UV不对称性

    算法效果的AB测试,是指在相同的应用场景下,对比不同算法的效果.通常的做法是,按照PV或UV随机分配流量到算法上,计算算法的CTR或转化率进行对比.为了表述简单,我们假设参与对比的算法有两个,比较的指 ...

最新文章

  1. 多个Google账户合并(共享)数据
  2. easyui datagrid 多表头数据错位_表格数据检索(二)
  3. 擦窗机器人测试标准_擦窗机器人,我选择玻妞的三个理由!
  4. 华为5G英国首秀,BBC主持人震惊了!到底网速有多快?
  5. c语言输入字符时控制符%c前加空格的原因解释
  6. java 提取电话号码_java – 如何使用正则表达式提取字符串的电话号码?
  7. 米拓建站系统(MetInfo CMS)文章定时发布软件
  8. Golang笔记—面向对象编程
  9. 并行程序设计模式--Master-Worker模式
  10. 10分钟虚拟设备接入阿里云IoT平台实战
  11. Python零基础入门(五)——文本文件读写和操作[学习笔记]
  12. Route@简单应用
  13. 在线教育app平台搭建招生系统教培系统源码
  14. 【C语言视频教程完整版】从入门到进阶,适合C语言初学者计算机考研党考计算机二级大一大二学生学习观看~~~
  15. 软考架构师 | 论文
  16. 串行加法器和并行加法器_N位并行加法器(4位二进制加法器和减法器)
  17. Tips-不下载PS制作电子签名
  18. 曾维沛云推广:全网落地营销为广西南宁企业带来精准客户订单
  19. 第11章实验1:学生成绩管理系统V4.0(C语言)
  20. Rockchip RK3566、RK3588、RV1109系统芯片详细参数介绍

热门文章

  1. photos怎么改成中文_picsart怎么设置中文?picsart怎么改成中文字体教程
  2. 什么是特征工程?如何进行特征工程?超详细解读
  3. 图像去雾/图像去雨(matlab/python)
  4. 系统架构师(一)选择题
  5. 系统 应用程序 提示 初始化失败 或 无法加载模块 等错误
  6. Python数据全球人口数据
  7. cadence allegro 17.2中的正负片
  8. java localdate_Java LocalDate now()用法及代码示例
  9. Spark 学习【二】
  10. CodeBlocks如何将英文环境改为中文