算法学习记录(五十)

131 阅读1分钟

问:

  1. 给定一个字符串str,可以通过移除字符使得str变成回文串。问有多少种移除方案
  2. 在一个无序数组中,求第k小的数
  3. 假设正数1,裂开的方式有一种:1;正数2:(1,1),(2);正数3:(1,1,1),(1,2),(3)。正数4:(1,1,1,1),(1,3),(2,2),(4)。给定一个正数n,求裂开的方法数

解:

  1. 相当于求有多少个回文子序列
function getAllNums(str) {
    const dp = []
    for (let i = 0; i <str.length; i++) {
        dp[i] = []
        for (let j = 0; j < str.length; j++) {
            if (i > j) {
                dp[i][j] = 0
            }
            if (i === j) {
                dp[i][j] = 1
            }
        }
    }
    for (let i = str.length - 2; i >= 0; i--) {
        for (let j = i + 1; j < str.length; j++) {
            dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1]
            if (str[i] === str[j]) {
                dp[i][j] += dp[i + 1][j - 1] + 1
            }
        }
    }
    return dp[0][str.length - 1]
}
// 基于快排的方法
function findKthNum(arr, k) {
    function getRes(left, right) {
        if (left >= right) return
        const target = arr[Math.floor((Math.random() * (right - left) + left))]
        const { smallIdx, bigIdx } = partition(left, right, target)
        if (k > smallIdx && k <= bigIdx) {
            return arr.slice(0, k)
        }
        if (k <= smallIdx) {
            return getRes(left, smallIdx)
        } else {
            return getRes(bigIdx, right)
        }
    }
    return getRes(0, arr.length - 1)
    function partition(left, right, target) {
        let smallIdx = left - 1
        let bigIdx = right + 1
        let pos = left
        while (pos < bigIdx) {
            if (arr[pos] < target) {
                [arr[smallIdx + 1], arr[pos]] = [arr[pos], arr[smallIdx + 1]]
                smallIdx++
                pos++
            } else if (arr[pos] === target) {
                pos++
            } else {
                [arr[bigIdx - 1], arr[pos]] = [arr[pos], arr[bigIdx - 1]]
                bigIdx--
            }
        }
        return {
            smallIdx,
            bigIdx
        }
    }
}
function getAllNums(n) {
    const dp = []
    for (let i = 0; i <= n; i++) {
        dp[i] = []
        for (let j = 0; j <= n; j++) {
            if (j === 0 || i === j) {
                dp[i][j] = 1
                continue
            }
            if (i > j) {
                dp[i][j] = 0
            }
        }
    }
    for (let i = n - 1; i >= 1; i--) {
        for (let j = i + 1; j <= n; j++) {
            dp[i][j] = 0
            dp[i][j] = dp[i + 1][j] + dp[i][j - i]
        }
    }
    return dp[1][n]
}