code

247 阅读4分钟

输入为只包含[a-z]的字符,去掉字符串中所有的b和ac

// ddaaabbbbbbbcccg => ddg
// adc => adc

function handleStr(str) {
    let newstr = str.split(""); //  1
    newstr = newstr.filter((e, i) => e !== "b");
    let b = new Array();
    let j = 0;
    for (let i = 0; i < newstr.length; i++) {
        if (newstr[i] !== "c") {
            b[j] = newstr[i];
            j++;
        }
        if (newstr[i] == "c") {
            if (j > 0 && b[j - 1] == "a") {
                b[j - 1] = "";
                j--;
            } else {
                b[j] = newstr[i];
                j++;
            }
        }
    }
    return b.join("");
}
console.log(handleStr("ddaaabbbbbbbcccg"));

平衡点问题 一个数组中的元素,如果其前面的部分等于后面的部分,那么这个点的位序就是平衡点。

比如列表numbers = [1, 3, 5, 7, 8, 25, 4, 20],25前面的元素总和为24,25后面的元素总和也是24,那么25就是这个列表的平衡点。
function get(arr) {
    let sum = 0,
        sumleft = 0,
        sumright = 0;
    for (let i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    for (let j = 1; j < arr.length; j++) {
        sumleft += arr[j - 1];
        sumright = sum - sumleft - arr[j];
        while (sumleft === sumright) {
            return j;
        }
    }
}

实现转换方法,把原始 list 转换成树形结构

const list = [
  { key: 1, data: 'A', parentKey: 0 },
  { key: 2, data: 'B', parentKey: 0 },
  { key: 3, data: 'C', parentKey: 1 },
  { key: 4, data: 'D', parentKey: 1 },
  { key: 5, data: 'E', parentKey: 2 },
  { key: 6, data: 'F', parentKey: 3 },
  { key: 7, data: 'G', parentKey: 2 },
  { key: 8, data: 'H', parentKey: 4 },
];
const result = convert(list);
function convert(list) {
    // your code
    const res = [];
    const map = list.reduce((res, v) => ((res[v.key] = v), res), {});
    for (const item of list) {
        if (item.parentKey === 0) {
            res.push(item);
            continue;
        }
        if (item.parentKey in map) {
            const parent = map[item.parentKey];
            parent.children = parent.children || [];
            parent.children.push(item);
        }
    }
    return res;
}

// [
//   {
//     key: 1,
//     data: 'A',
//     parentKey: 0,
//     children: [
//       { key: 3, data: 'C', parentKey: 1, children: [{ key: 6, data: 'F', parentKey: 3 }] },
//       { key: 4, data: 'D', parentKey: 1, children: [{ key: 8, data: 'H', parentKey: 4 }] },
//     ],
//   },
//   {
//     key: 2,
//     data: 'B',
//     parentKey: 0,
//     children: [
//       { key: 5, data: 'E', parentKey: 2 },
//       { key: 7, data: 'G', parentKey: 2 },
//     ],
//   },
// ];


数组去重

let ary = [12, 23, 12, 15, 25, 23, 25, 14, 16];
console.log(unique(ary));
1. IndexOf法
function unique(ary){
   let arr = [];
   for (let i = 0; i < ary.length; i++) {
      let item = ary[i],
         args = ary.slice(i + 1)
      if (args.indexOf(item) < 0) {
         arr.push(item)
      }
   }
   return arr;
}
2. forEach/includes
function unique(ary) {
    let arr = [];
    ary.forEach((i) => {
        return arr.includes(i) ? "" : arr.push(i);
    });
    return arr;
}
3.includes
function unique(ary) {
    let arr = [];
    for (let i = 0; i < ary.length; i++) {
        if (!arr.includes(ary[i])) {
            arr.push(ary[i]);
        }
    }
    return arr;
}
4. 先排序,再相邻元素比较
function unique(ary) {
    const formatArr = ary.sort();
    let arr = [];
    // console.log(formatArr);
    for (let i = 0; i < formatArr.length; i++) {
        if (formatArr[i] !== formatArr[i + 1]) {
            arr.push(formatArr[i]);
        }
    }
    return arr;
}

利用call求和
let result = sum(1, 2, 3);
console.log(result);
function sum(){
    内置slice和自己写的代码只有this指向不同
    let arr=[].slice.call(arguments)
    return arr.reduce((item,result)=>item+result)
}

两数之和

nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
function twosum (nums,target){
    const map = new Map();
    for(let i =0;i<nums.length;i++){
        const complement = target- nums[i];
        if(map.has(complement)){
            return [map.get(complement),i]
        } else {
            map.set(nums[i],i);
        }
    }
    return []
}
let nums = [2, 7, 11, 15];
console.log(twosum(nums, 18));

实现 get(obj, 'x.y.z') ,判断o.x.y.z是否存在

console.log(get({ a: { b: { c: 666 } } }, "a.b.c")); //666
function get(obj, str) {
    let arr = str.split('.');
    arr.forEach(i=>{
        obj = obj&&obj[i];
    })
    return obj;
}

数组相邻元素去重

[1,1,2,3,4,4,3,3]=>[1,2,3,4,3]
let arr = [1, 1, 1, 1, 2, 3, 4, 4, 3, 3, 1, 1];
console.log(unique(arr));
function unique(arr) {
   for (let i = 0; i < arr.length - 1; i++) {
       if (arr[i] === arr[i + 1] || arr[i] === arr[i - 1]) {
           arr.splice(i, 1);
           i--;
       }
   }
   return arr;
}

实现一个倒计时 运行后控制台立即输出10,此后每隔一秒打印出来9.8.7.6.5.4.3.2.1

for (let i = 10; i >= 0; i--) {
    setTimeout(() => {
        console.log(i);
    }, 1000 * (10 - i));
}

二分查找

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4
输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1
function search(nums, target) {
    let left = 0,
        right = nums.length - 1;
    while (left <= right) {
        let mid = Math.floor((left + right) / 2);
        if (nums[mid] === target) {
            return mid;
        } else if (target < nums[mid]) {
            right = mid - 1;
        } else {
            left = mid + 1;
        }
    }
    return -1;
}
let nums = [-1, 0, 3, 5, 9, 12];
console.log(search(nums, 9));

数组扁平化

已知如下数组:
let arr = [[1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
// 编写一个程序将数组扁平化去并除其中重复部分数据, 最终得到一个升序且不重复的数组
console.log(Array.from(new Set(arr.flat(Infinity))).sort((a, b) => a - b));

function flatten(arr) {
    return arr.reduce((prev, item) => {
        return prev.concat(Array.isArray(item) ? flatten(item) : item);
    }, []);
}

JSON.stringify(ary)


let result = [];
let fn = function (ary) {
    for (let i = 0; i < ary.length; i++) {
        let item = ary[i];
        if (Array.isArray(ary[i])) {
            fn(item);
        } else {
            result.push(item);
        }
    }
};

let a =?数字==对象,对象会先调用tostring方法在调用number()

let a = {
    i: 0,
    toString() {
        return ++this.i;
    },
};
if (a == 1 && a == 2 && a == 3) {
    console.log("ok");
}

在从左向右和从上往下皆为升序的二维数组中,查找一个数是否存在,存在的话输出它的位置。

let arr = [
    [1, 2, 3, 15],
    [4, 5, 10, 16],
    [7, 8, 11, 17],
];
function find(target, arr) {
    let i = arr.length - 1,
        j = 0;
    while (i >= 0 && j < arr[i].length) {
        if (target == arr[i][j]) {
            return [i, j];
        } else if (target > arr[i][j]) {
            j++;
        } else {
            i--;
        }
    }
    return false;
}
console.log(find(17, arr));

给定任意二维数组,输出所有的排列组合项。比如 [['A','B', 'C'], ['a','b', 'c'], [1, 2]],输出 ['Aa1','Aa2','Ab1','Ab2','Ba1','Ba2','Bb1','Bb2']

let arr = [
    ["A", "B", "C"],
    ["a", "b", "c"],
    [1, 2],
];
function getResult(arrA, arrB) {
    if (!Array.isArray(arrA) || !Array.isArray(arrB)) {
        return;
    }
    if (arrA.length === 0) {
        return arrB;
    }
    if (arrB.length === 0) {
        return arrA;
    }
    let result = [];
    for (let i = 0; i < arrA.length; i++) {
        for (let j = 0; j < arrB.length; j++) {
            result.push(String(arrA[i]) + String(arrB[j]));
        }
    }
    return result;
}
function findAll(arr) {
    return arr.reduce((total, current) => {
        return getResult(total, current);
    }, []);
}
console.log(findAll(arr));

洗牌

let arr = ["1", "2", "3", "4", "5"];
function shuffle(arr) {
    let temp = "";
    for (let i = arr.length - 1; i > 0; i--) {
        let idx = Math.floor(Math.random() * (i + 1));
        temp = arr[idx];
        arr[idx] = arr[i];
        arr[i] = temp;
    }
    return arr;
}
console.log(shuffle(arr));

abcdefg@meituan.com=> ab****@meituan.com

let reg = /(.{2}).+(@.+)/g;
let str = "asbefg@meituan.com";
console.log(str.replace(reg, "$1****$2"));

最长回文子字符串

188271617237818_.pic.jpg

let str = "sdfsdfdddsd";
function getLongestStr(s) {
    if (s.length < 2) {
        return s;
    }
    let start = 0;
    let maxlength = 1;
    function expandAeoundCenter(left, right) {
        while (left >= 0 && right < s.length && s[left] === s[right]) {
            if (right - left + 1 > maxlength) {
                maxlength = right - left + 1;
                start = left;
            }
            left--;
            right++;
        }
    }
    for (let i = 0; i < s.length; i++) {
        expandAeoundCenter(i - 1, i + 1);
        expandAeoundCenter(i, i + 1);
    }
    return s.substring(start, start + maxlength);
}
console.log(getLongestStr(str));

返回['abc,'ab'] let arr = ["abc", "abc", "ab", "ab", "123", "dsfa123"];

function getMax(arr) {
    let obj = {};
    let max = 0;
    arr.map((i) => {
        if (obj[i]) {
            obj[i] += 1;
        } else {
            obj[i] = 1;
        }
        max = Math.max(max, obj[i]);
    });
    return Object.keys(obj).filter((i) => obj[i] === max);
}
console.log(getMax(arr));

冒泡排序(O(n^2))

function bubble(arr) {
let ary = [12, 8, 24, 16, 1];
function bubble(arr) {
    let len = arr.length - 1;
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < len - i; j++) {
            if (arr[j] > arr[j + 1]) {
                let temp = arr[j + 1];
                arr[j + 1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}
console.log(bubble(ary));

插入排序(O(n^2))

function insert(ary) {
    //准备一个新数组,用来存储拿到手里的牌
    let handle = [];
    handle.push(ary[0]);
    // 从第二项开始一次抓牌,一直把台面上的牌抓光
    for (let i = 1; i < ary.length; i++) {
        //A是新抓的牌
        let A = ary[i];
        // 和handle手里的牌依次比较(从后往前比)
        for (let j = handle.length - 1; j >= 0; j--) {
            // 每一次要比较的手里的牌
            let B = handle[j];
            // 如果当前新牌A比要比较的牌B大了,把A放到B的后面
            if (A > B) {
                handle.splice(j + 1, 0, A);
                break;
            }
            if (j === 0) {
                handle.unshift(A);
            }
        }
    }
    return handle;
}
let ary = [12, 8, 24, 16, 1];
console.log(insert(ary));

快速排序O(n*log2(n))

function quick(ary) {
    // 结束递归(当数组中小于等于一项,则不用处理)
    if (ary.length < 2) {
        return ary;
    }
    // 找到数组的中间项,在原有的数组中把它移除
    let midIdx = Math.floor(ary.length / 2);
    let midVal = ary.splice(midIdx, 1)[0];
    // 准备左右两个数组,循环剩下数组中的每一项,比当前项小的放到左边数组中,比当前项大的放到右边数组中
    let leftAry = [],
        rightAry = [];
    for (let i = 0; i < ary.length; i++) {
        let item = ary[i];
        item < midVal ? leftAry.push(item) : rightAry.push(item);
    }
    return quick(leftAry).concat(midVal, quick(rightAry));
}
let ary = [12, 8, 24, 16, 1];
console.log(quick(ary));

千分位

let num = 12473264365632;
function format(num) {
    let str = num + "";
    return str
        .split("")
        .reverse()
        .reduce((prev, next, index) => {
            return (index % 3 ? next : next + ",") + prev;
        });
}
console.log(format(12345678));

随机选取 10~100 之间的 10 个不重复的整数,存入一个数组,并按从小到大顺序进行排序

function random(start, end) {
    let num = end - start + 1;
    return Math.floor(Math.random() * num + start);
}
function getRandomArray(length) {
    let set = new Set();
    function ran(length) {
        for (let i = 0; i < length; i++) {
            set.add(random(10, 100));
        }
        if (set.size < length) {
            ran(length - set.size);
        }
    }
    ran(length);
    return Array.from(set).sort((a, b) => a - b);
}
console.log(getRandomArray(10));

斐波那契数列

输入:2
输出:1
解释:F(2) = F(1) + F(0) = 1 + 0 = 1
function fib(n) {
    if (n === 0) {
        return 0;
    }
    if (n === 1 || n === 2) {
        return 1;
    }
    return fib(n - 2) + fib(n - 1);
}
console.log(fib(4))
function fib(n) {
    if (n <= 1) {
        return 1;
    }
    let arr = [1, 1];
    //即将要创建多少个
    let i = n + 1 - 2;
    while (i > 0) {
        let a = arr[arr.length - 2],
            b = arr[arr.length - 1];
        arr.push(a + b);
        i--;
    }
    return arr[arr.length - 1];
}
console.log(fib(7))

和为n的正数序列

例如:输入15
结果:[[1,2,3,4,5],[4,5,6],[7,8]]
function createArr(n, len) {
    let arr = new Array(len).fill(null),
        temp = [];
    arr[0] = n;
    arr = arr.map((i, index) => {
        if (i === null) {
            i = temp[index - 1] + 1;
        }
        temp.push(i);
        return i;
    });
    return arr;
}
function fn(count) {
    let result = [];
    let middle = Math.ceil(count / 2);
    for (let i = 1; i < middle; i++) {
        for (let j = 2; ; j++) {
            let total = i + (i + j - 1) * (j / 2);
            if (total > count) {
                break;
            } else if (total === count) {
                result.push(createArr(i, j));
                break;
            }
        }
    }
    return result;
}
console.log(fn(21))

合并两个有序数组

let arr1 = [1, 5];
let arr2 = [7, 8, 30, 100];
let arr = [];
let i = 0,
    j = 0,
    k = 0;
while (i < arr1.length && j < arr2.length) {
    console.log(arr, i, j, k);
    if (arr1[i] < arr2[j]) {
        arr[k] = arr1[i];
        i++;
        k++;
    } else {
        arr[k] = arr2[j];
        j++;
        k++;
    }
}
if (i < arr1.length) {
    console.log("bb", arr1.slice(i));
    arr = arr.concat(arr1.slice(i));
}
if (j < arr2.length) {
    console.log("aa", arr2.slice(j));
    arr = arr.concat(arr2.slice(j));
}
console.log(arr);

有效的括号

function isValid(s) {
    let stack = [];
    let mappings = new Map();
    mappings.set("(", ")");
    mappings.set("[", "]");
    mappings.set("{", "}");
    for (let i = 0; i < s.length; i++) {
        if (mappings.has(s[i])) {
            stack.push(mappings.get(s[i]));
        } else if (stack.pop() !== s[i]) {
            return false;
        }
    }
    if (stack.length !== 0) {
        return false;
    }
    return true;
}
console.log(isValid("([[[)]]])"));