算法

206 阅读2分钟

算法

找到重复的数字

/*---- 数组a[N],存放了数字1至N-1,其中某个数字重复出现了一次,要求写一函数find(arr),找出该数字,时间复杂度必须为O(N),空间复杂度不能是O[N] ----*/
function findRepeatNum(arr, n) {
    if (n < 0 || arr.length === 0) return -1;
    const length = arr.length;
    const noRepeatSum = (n * (n + 1)) / 2;
    let repeatSum = 0;
    for (let i = 0; i < length; i++) {
        repeatSum += arr[i];
    }
    return n - (noRepeatSum - repeatSum);
}

LazyMan

class _LazyMan {
    constructor(name) {
        this.tasks = [];
        const task = () => {
            console.log(`Hi! This is ${name}`);
            this.next();
        }
        this.tasks.push(task);
        setTimeout(() => {               // 把 this.next() 放到调用栈清空之后执行
            this.next();
        }, 0);
    }

    next() {
        const task = this.tasks.shift(); // 取第一个任务执行
        task && task();
    }

    sleep(time) {
        this._sleepWrapper(time, false);
        return this;                     // 链式调用
    }

    sleepFirst(time) {
        this._sleepWrapper(time, true);
        return this;
    }

    _sleepWrapper(time, first) {
        const task = () => {
            setTimeout(() => {
                console.log(`Wake up after ${time}`);
                this.next();
            }, time * 1000)
        }
        if (first) {
            this.tasks.unshift(task);     // 放到任务队列顶部
        } else {
            this.tasks.push(task);        // 放到任务队列尾部
        }
    }

    eat(name) {
        const task = () => {
            console.log(`Eat ${name}`);
            this.next();
        }
        this.tasks.push(task);
        return this;
    }
}

function LazyMan(name) {
    return new _LazyMan(name);
}

LRU

class LRU {
    constructor(capacity = 10) {
        this.capacity = capacity;
        this.cache = new Map();
    }

    // 1. 获取值,如果值存在的话,删除原来的值,把新值放入头部,如果不存在的话,直接插入头部
    get(key) {
        let item = this.cache.get(key);
        if (item) // refresh key
        {
            this.cache.delete(key);
            this.cache.set(key, item);
        }
        return item;
    }

    // 设置值,
    // 1. 如果值存在,就删除原来的值,并把设置的值放入头部
    // 2. 如果已经达到容量,就删除最尾部的值,然后添加值
    set(key, value) {
        if (this.cache.has(key)) {
            this.cache.delete(key);
        } else if (this.capacity === this.cache.size) {
            this.cache.delete(this._first());
        }
        this.cache.set(key, value);
    }

    // 获取移除最底部的值
    _first() {
        return this.cache.keys().next().value;
    }
}

字符串转换成数字

function stringToNums (str) {
    if (str.length === 0) return 0
    const arr = str.split('').reverse()
    return arr.reduce((sum, num, index) => {
        return sum += num * Math.pow(10, index)
    }, 0)
}

交换位置得到最大的值

function numToArray(num) {
    const arr = [];
    while (num > 0) {
        arr.unshift(num % 10);
        num = num / 10 | 0;
    }
    return arr;
}

function swap(oldArr, oldIndex, diff) {
    let temp = oldArr[oldIndex];
    oldArr[oldIndex] = oldArr[diff];
    oldArr[diff] = temp;
}

function swapNumGetMaxValue(num) {
    const oldArr = numToArray(num);
    const newArr = [...oldArr].sort((a, b) => b - a);
    console.log(newArr);
    let diff = -1;

    for (let i = 0; i < oldArr.length; i++) {
        if (oldArr[i] !== newArr[i]) {
            diff = i;
            break;
        }
    }
    if (diff === -1) return num;
    // 找到新数字在旧数字中的位置
    const oldIndex = oldArr.findIndex(num => num === newArr[diff]);
    swap(oldArr, oldIndex, diff);
    return Number.parseInt(oldArr.join(''));
}

回文数字

function isMirrorTwo(num) {
    if (num < 0 || (num / 10 === 0 && num != 0)) return false;
    let n = 0;
    while (num > n) {
        n = n * 10 + num % 10;
        num = parseInt(num / 10);
    }
    return num === n || parseInt(n / 10) === num;
}

子字符串

String.prototype.indexOf = function(sub){
    var pos = 0, len = this.length, sublen = sub.length, i = 0;
    while(i < len){
        same = this.charAt(i) === sub.charAt(pos);
        i = same ? i + 1: i - pos + 1;
        pos = same ? pos + 1: 0;
        if (pos === sublen) {
            console.log(i);
            return i - sublen;
        }
    }
    return -1;
};
console.log('fghijghijc'.indexOf('ghijc'));

最长连续递增序列

function findArr(arr) {
    let length = arr.length;
    if (length === 0) return 0;
    let max = 0;
    let count = 1;
    for (let i = 0; i < length - 1; i++) {
        if (arr[i] < arr[i + 1]) {
            count++;
        } else {
            max = Math.max(count, max);
            count = 1;
        }
    }
    max = Math.max(count, max);
    return max;
}

环形链表

// 1. 快慢指针
const cycle2 = function (linkedList) {
    let start = linkedList.head;
    let end = start.next;
    while (start !== end) {
        // 没有环就null
        if (end === null || end.next === null) return false;
        start = start.next;
        end = end.next.next;
    }
    return true;
};