手写深拷贝
思路见代码注释
function depclon(sourceObj, map) {
// 判断是否为对象或者数组
// object()判断不严谨,如 var a = Number(1), Object(a) === a 无法判断
// 此处 需要改为 typeof sourceObj === 'object' && object !== null判断
if(Object(sourceObj) !== obj) {
return sourceObj
}
// 考虑循环引用,如a.ref = a
if(!map) {
map = new WeakMap()
}
// 判断是否是数组还是对象,
const target = Array.isArray(sourceObj) ? [] : {}
if(map.has(sourceObj)) return sourceObj.get(sourceObj)
map.set(sourceObj, target)
// for in可以通用 对 object和array遍历
for (const key in sourceObj) {
if (Object.hasOwnProperty.call(sourceObj, key)) {
const element = sourceObj[key];
if(Object(element) === element) {
target[key] = depclon(element, map)
} else {
target[key] = map
}
}
}
return target
}
可参考 blog.csdn.net/qq_41846861…
合并两个有序数组
思路: 其实就是以一个数组为基准,不断遍历另外一个数组,以下面的例子来说就是 用b里面的第n项和a中的每一项作对比,找到合适的位置后插入,然后继续拿出b中的下一项继续
var a = [1,3,5]
var b = [2,4,6,8]
function merge(a, m, b, n) {
let i = 0
let j = 0
while(j < n) {
if(b[j] > a[i]) {
i++
} else {
a.splice(i++, 0,b[j++])
}
}
}
merge(a, 3, b, 4)
promise并发请求控制
思路: 用promise.all实现,比如要求同时并发3个请求,总共10个请求,那么用一个长度为3的空数组遍历,并用promise.all包裹,此时会并发三个请求,在每一个请求完成的时候将10个请求中剩余的(此时还有7个)请求循环调用,知道剩余请求为空
深度遍历 广度遍历
juejin.cn/post/695617… juejin.cn/post/692760…
面试真题 手写1
完成format函数,来对输入的对象转换成字符串并格式化打印。(不能用json.stringfry)
例1
obj = [1,2,[3,4]]
console.log(format(obj))
输出
[
1,
2,
[
3,
4
]
]
例2
obj = {name:'xiaoming',age:12,phone:[110,120,{other:130}],skill:{changtiao:80,rap:90,lanqiu:100}}
console.log(format(obj))
{
"name":'xiaoming',
"age": 12,
"phone":[
110,
120,
{
"other":130
}
],
"skill":{
"changtiao":80,
"rap":90,
"lanqiu":100
}
}
实现 本题也可叫做 # 模拟实现JSON.stringiry 的格式化输出
另外也可以 利用nodeJS中的util模块中的 util.inspect(obj[,options])
其他题目
手写lrucache (真题
两种思路, 在js中可利用特有的 map结构即可 segmentfault.com/a/119000003… 利用 双向链表(保证有序) + object(保证取值方便) juejin.cn/post/694842…
手写 userequest (真题
mobx redux 区别 (真题
最长递增子序列
typescript
- const func = (a, b) => a + b; 要求编写Typescript,要求a,b参数类型一致,都为number或者都为string
想了半天只想到用重载解决 ,泛型的话实现不了
function add(a:string, b:string): string;
//带有数字类型参数的函数 function add(a:number, b:number): number;
//函数定义
function add(a: any, b:any): any {
return a + b;
}
const dd = add(1,1)
const dd2 = add('1','3')
或者 interface的重载
手写 useprevious
为什么如下可以实现,因为 useEffect是在return之后执行,所以每次会返回上一次的值
function useprevies(value) {
const prevalueRef = useRef()
useEffect(()=>{
prevalueRef.current = state
})
rerurn prevalueRef.current
}
手写快速排序
分治 +递归
var testarr = [1,5,2,7,1,88,6,15]
function qrsort(arr = []) {
if(arr.length <= 1) return arr
const pivot =arr.shift()
const left = []
const right = []
arr.forEach(item => {
item < pivot ? left.push(item) : right.push(item)
})
return qrsort(left).concat([pivot], qrsort(right))
}
testarr(testarr)
大数相加
function plus(str1, str2) {
while(str1.length < str2.length) {
str1 = '0' + str1
}
while(str2.length < str1.length) {
str2 = '0' + str2
}
let res = '' // 结果
let pat = 0 // 进位
let i = str1.length -1
while(i >= 0) {
var ret = Number(str1[i]) + Number(str2[i]) + pat
res = ret % 10 + res
pat = ret> 10 ? 1 : 0
i --
}
return pat === 1 ? '1'+ res : res
}
判断左右括号
function isValid3(str) {
const arr = []
const lefttoright = {
'(': ')',
'{': '}',
"[": ']',
}
for(let i =0 ;i<str.length ;i++) {
let item = str[i]
if(lefttoright[item]) {
// zuo kuo hao
arr.push(item)
} else {
if(!arr.length) {
return false
}
const top = arr.pop()
if(lefttoright[top] !== item) {
return false
}
}
}
return !arr.length
}
isValid3('()')
jsbridge原理
注意 原生和webview中可以传递字符串 没办法传递函数 native在webview中声明一个对象 并包含方法 invoke:(name,param, success,errcess)=>{} 所以客户端通过维护一个 函数key映射 {callback_$1: callback1} 将key传递给native
选择排序
复杂度 o(n2), 双层for循环+交换两个变量
function selectsort(arr) {
let temp
let minidx
for(let i = 0; i<arr.length; i++) {
minidx = i
for(let j = i+1;j<arr.length; j++) {
if(arr[j] < arr[minidx]) {
minidx = j
}
}
let temp = arr[i]
arr[i]= arr[minidx]
arr[minidx] = temp
}
return arr
}
冒泡排序
双层循环
两两比较
每次循环能比较出一个最大值。
内层循环每次的终点-1
function bublesort(arr) {
for(let i = 0; i<arr.length; i++) {
for(let j = 0;j<arr.length-1-i; j++) {
if(arr[j] < arr[j+1]) {
let temp = arr[j]
arr[j] = arr[j+1]
arr[j+1] = temp
}
}
}
return arr
}
插入排序
和冒泡的区别, 冒泡复杂度o(n2), 插入比冒泡相对好一些,操作步骤较少
function insersort(arr) {
for(let i = 1; i<arr.length; i++) {
let preidx = i-1
let current = arr[i]
while(preidx >=0 && arr[preidx] > arr[i]) {
arr[preidx+1] = arr[preidx]
preidx--
}
arr[preidx+1] = current
}
return arr
}
希尔排序
function shellSort(array) {
if (array.length <= 1) return array; // 如果数组长度为1,直接返回
var gap = Math.floor(array.length / 2);
while (gap > 0) {
for (var i = gap; i < array.length; i++) {
var j = i;
var temp = array[j];
while (j > 0 && array[j - gap] > temp) { // 若array[j - gap]>temp(即array[j]) 则互换位置
array[j] = array[j - gap]; // 这里可看成是将 j-gap 后移一个 gap 位 //TODO 插入排序这里是后移一位
array[j - gap] = temp; // 由于不像插入排序那样需要比较很多个元素,而是两个数的比较,此处将大得值往前移一个 gap 位即可
j -= gap; // 跳出循环的条件
}
}
gap = Math.floor(gap / 2); // 减小增量
}
return array;
}
var arr = [9, 1, 2, 5, 7, 4, 8, 6, 3, 5];
console.log(shellSort(arr))
并归排序
function mergeSort(array) {
if (array.length <= 1) return array; // 如果数组长度为1,直接返回。等到merge中排序合并
var m = Math.floor(array.length / 2);
var left = mergeSort(array.slice(0, m)); // 不断递归调用最终排列好 left 数组
var right = mergeSort(array.slice(m, array.length)); // 不断递归调用最终排列好 right 数组
return merge(left, right);
}
// 排列并合并左右数组
function merge(left, right) {
var resArr = [] // 新的空数组
while (0 < left.length && 0 < right.length) { // 每次比较取出一个相对小的元素放入resArr中
resArr.push(left[0] <= right[0] ? left.shift() : right.shift()) // array.shift() 取第一个数,并移除该数组中的第一个数
}
return resArr.concat(left, right);
}
var arr = [8, 7, 6, 5, 4, 3, 2, 1];
console.log(mergeSort(arr)); // [1, 2, 3, 4, 5, 6, 7, 8]
计数排序
function countingSort(arr, maxValue) {
var bucket = new Array(maxValue + 1),
sortedIndex = 0;
arrLen = arr.length,
bucketLen = maxValue + 1;
for (var i = 0; i < arrLen; i++) {
if (!bucket[arr[i]]) {
bucket[arr[i]] = 0;
}
bucket[arr[i]]++;
}
for (var j = 0; j < bucketLen; j++) {
while(bucket[j] > 0) {
arr[sortedIndex++] = j;
bucket[j]--;
}
}
return arr;
}
桶排序
有弊端,了解思想即可, 分为多个桶,每个桶里分别排序,然后在合并, 缺陷为 每个桶的大小不好确定,比如0.11, 0.12, 0.13 , 0.14, 0.91, 1.00
有题目得知,数值范围在0-1之间, 我们可以平均分为四个桶, 0-0.25, 0.25-0.5, 0.5-0.75, 0.75-1.00,
但是缺陷为 数据明显都会分布在0.11-0.15之间, 所以导致四个桶 数据不均
基数排序
适用于正整数 先个位数排序,在十位数排序,在百位排序, 以此类推 juejin.cn/post/703890…
计算 ’2+4/4-1‘
letcode 224 和227 ,用栈去解决, 遍历字符串, 如果是数字的话复制给全局 累计 判断四则符号, 加号的话 数字push进数组 -好的话 数字加负号push进数组 乘除的话 先运算在 push进数组 用reduce求和 leetcode-cn.com/problems/ba…