算法Ten

有序数组中找大于等于 n 最左边的数

export const erfen = (arr: number[], n: number) => {
    let len = arr.length
    if (!arr || len < 2 || typeof n !== 'number') return arr

    let curValue = 0, midIndex, midValue
    let leftNums = [1]
    let rightNums = []
    let time = 0
    let handleArr = JSON.parse(JSON.stringify(arr))

    while (leftNums.length + rightNums.length > 0) {
        time++
        if (time > 100) {
            console.log('死循环');
            return
        }
        // debugger

        midIndex = Math.floor(handleArr.length / 2)
        midValue = handleArr[midIndex]
        leftNums = handleArr.slice(0, midIndex - 1)
        rightNums = handleArr.slice(midIndex + 1, handleArr.length)

        if (midValue >= n) {
            curValue = midValue
            handleArr = leftNums
        } else {
            handleArr =  
        }
    }
    return curValue
}

优化简洁版

思路:如果传递的 n 大于等于 midValue 那就将右边的下标往中间挪动。这样就可以开始从 0 到 midIndex 之前找最小的值。如果小于,midIndex 到 len - 1 找小的最左边的值。

// 有序数组中找大于等于 n 最左边的数
export const erfen = (arr: number[], n: number) => {
    let len = arr.length
    if (!arr || len < 2 || typeof n !== 'number') return -1

    let leftIndex = 0
    let rightIndex = len - 1
    let ans = -1

    while(leftIndex <= rightIndex){
        let midIndex = Math.floor((leftIndex + rightIndex)/ 2)

        if (arr[midIndex] >= n) {
            ans = midIndex
            rightIndex = midIndex - 1
        }else{
            leftIndex = midIndex + 1
        }
    }

    return arr[ans]
}
console.log(erfen([1, 2, 3, 3, 3, 3, 4, 5, 5, 7, 8, 10, 11, 13], 3));

反转链表

  1. 保存gnext数据
  2. gPrev赋值给当前 head 节点的 next 节点
  3. 移动 gPrev 到下一步 (head 赋值给 gPrev)
  4. gPrev 接收搭配报错的gNext数据
interface INode {
    value: number,
    next?: INode,
    prev?: INode
}
export const linkReverseFunc = (head: INode) => {
    let prev: INode | undefined = undefined
    let next: INode | undefined = undefined
    while (head.next) {
        // 保存next数据
        next = head.next
        // 将当前节点的下一个指向prev 如果是第一次 则为空 如果第二次 在第一步prev已经赋值给了当前head节点
        head.next = prev
        // 当前节点给下一次的prev使用
        prev = head
        // 下一个节点变成开始全局记录的next 
        head = next

        if (!prev.next) {
            delete prev.next
        }
    }

    if(!head.next){
        console.log(head,'head');
        head.next = prev
        prev = head
    }

    return prev
}
let nodeinit: INode = {
    value: 100,
    next: {
        value: 200,
        next: {
            value: 300,
            next: {
                value: 400,
                next: {
                    value: 500,
                }
            }
        }
    }
}
console.log(linkReverseFunc(nodeinit), 'test');

并查集

如果 多个用户 a 或者 b 或者 c 的字段值一样 就合并
返回合并之后的用户加上count字段

思路:声明多个集合,如果,没出现过,就set到map里面,如果出现过,就count+1
下次再来。。。太难了,有思路再来。

// users合并
/* [
        { a: 1, b: 2, c: 3},
        { a: 1, b: 3, c: 4},
        { a: 8, b: 9, c: 10},
        { a: 10, b: 9, c: 8}
    ]
    思路:三个集合 aMap bMap cMap
    默认为空 最后会变成 aMap:  { a: 
                                { a: 1, b: 2, c: 3, count: 2}
                                { a: 8, b: 9, c: 10} }
                                { a: 10, b: 9, c: 8}
                            }, 

                     bMap: { a: { a: 2, b: 3, c: 9, count: 3}}
                     cMap: { a: { a: 3, b: 4, c: 10, count: 4}}
*/
export const mergeUser = (users: IUserInfo[]) => {
    let aMap = new Map()
    let bMap = new Map()
    let cMap = new Map()
    users.forEach(item => {
        // 如果三个集合都没有这个item 那就放在
        if (!aMap.has(item.a) && !bMap.has(item.b) && !cMap.has(item.c)) {
            aMap.set(item.a, { ...item, count: 1 })
            bMap.set(item.b, { ...item, count: 1 })
            cMap.set(item.c, { ...item, count: 1 })
            // return
        }
        if (aMap.has(item.a)) {
            let aItem = aMap.get(item.a)
            aItem.count++
            // return
        }
        if (bMap.has(item.b)) {
            let bItem = bMap.get(item.b)
            bItem.count++
            // return
        }
        if (cMap.has(item.c)) {
            let cItem = cMap.get(item.c)
            cItem.count++
            // return
        }
    })
    console.log(aMap, bMap, cMap, 'abc');
}
mergeUser([{ a: 1, b: 2, c: 3 }, { a: 1, b: 3, c: 4 }, { a: 8, b: 9, c: 10 }, { a: 10, b: 9, c: 8 }])

覆盖绳子最多的点数

// 盖住最大值的绳子上的点
export const ropeCoveringPoint = (arr: number[], n: number) => {
    let left = 0, right = 0, max = 0, len = arr.length

    while (left < len) {
        while (left < len && arr[right] - arr[left] <= n) {
            right++
        }
        // debugger
        max = Math.max(max, right - (left++))

    }

    return max
}

console.log(ropeCoveringPoint([1, 3, 6, 8, 10, 12, 13, 17, 19, 24, 28, 31], 16));

字符串只有 ”G“和”B“ 如果要把G放最左边,B放最右边,求需要移动几部才能让所有g在左边,b在右边。

export const moveChar = (str: string) => {
    let len = str.length
    let count = 0
    let gCount = 0
    for (let i = 0; i < len; i++) {
        if (str[i] === 'G') {
            gCount ++
            let res = (i - gCount) < 0 ? 0 : (i - gCount)
            // debugger
            count = count + res + 1
        }
    }

    return count
}
console.log(moveChar('GGBBGGGBBBGGGGBBBB'));

你可能感兴趣的:(javascript,算法,javascript,vue.js)