算法学习记录(十九)

127 阅读1分钟

问:

  1. 逆序一个数组
  2. 给一串数字,1~26与英文字母相对应。比如111可以转为AAA或者AK或者KA。请问有多少种转法?
  3. 给两个数组weight、values。分别代表物品的大小和价值。如果有一个包的能背的重量上限是N,可以得到的最大价值是多少。

解:

  1. 利用递归函数压栈保存弹出的数字,这种解法比较抽象并且也无必要,只是为了学习递归
    function getLastItem(arr) {
        const item = arr.pop()
        if (!arr.length) {
            return item
        } else {
            const last = getLastItem(arr)
            arr.push(item)
            return last
        }
    }
    function reverse(arr) {
        if (!arr.length) return
        const lastItem = getLastItem(arr)
        reverse(arr)
        arr.push(lastItem)
        return arr;
    }
  1. 从0开始递归,i走到str.length就返回1个转法。0无法转成字母直接返回0,碰到1就判断i+1是否越界,不越界递归结果就加上双数转字母的情况。碰到2就判断i+1是否越界并且是否小于26,不越界递归结果就加上双数转字母的情况。碰到3~9就正常递归下去。
function getAllMakeUp(str) {
    function getRes(i) {
        if (i === str.length) return 1
        if (str[i] === '0') return 0
        if (str[i] === '1') {
            let res = getRes(i + 1)
            if (i + 1 < str.length) res += getRes(i + 2)
            return res
        }
        if (str[i] === '2') {
            let res = getRes(i + 1)
            if (i + 1 <str.length && str[i + 1] < 7) res += getRes(i + 2)
            return res
        }
        return getRes(i + 1)
    }
    return getRes(0)
}
  1. alreadyWeight(前面所选物品重量)+ 当前重量 大于背包大小时,意味着不能再获得价值了,返回0。当i走到结尾时,意味着已经没有物品可以放了,不能再获得价值。那么递归两种情况,一种是放当前物品,另一种是不放。选出两者中能获取的价值的最大值。
function getMostValue(weight, values, N) {
    function getRes(i, alreadyWeight) {
        if (alreadyWeight + weight[i] > N) return 0
        if (i === values.length) return 0
        return Math.max(getRes(i + 1, alreadyWeight), values[i] + getRes(i + 1, alreadyWeight + weight[i]))
    }
    return getRes(0, 0)
}