最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 【一天一大 lee】拼接最大数 (难度:困难) - Day20211202

    正文概述 掘金(前端小书童)   2020-12-02   322

    题目:

    给定长度分别为  m  和  n  的两个数组,其元素由  0-9  构成,表示两个自然数各位上的数字。现在从这两个数组中选出 k (k <= m + n)  个数字拼接成一个新的数,要求从同一个数组中取出的数字保持其在原数组中的相对顺序。

    求满足该条件的最大数。结果返回一个表示该最大数的长度为  k  的数组。

    说明: 请尽可能地优化你算法的时间和空间复杂度。

    示例:

    1. 示例 1:
    输入:
    nums1 = [3, 4, 6, 5]
    nums2 = [9, 1, 2, 5, 8, 3]
    k = 5
    输出:
    [9, 8, 6, 5, 3]
    1. 示例 2:
    输入:
    nums1 = [6, 7]
    nums2 = [6, 0, 4]
    k = 5
    输出:
    [6, 7, 6, 0, 4]
    1. 示例 3:
    输入:
    nums1 = [3, 9]
    nums2 = [8, 9]
    k = 3
    输出:
    [9, 8, 9]

    提示:

    • 0 <= nums.length <= 105
    • -109 <= nums[i] <= 109
    • nums  是一个非递减数组
    • -109 <= target <= 109

    抛砖引玉

    思路:

    假设已知分类从 nums1 和 nums2 中取出 x,y 个元素(x+y=k) 那么问题就转换成了:

    1. 从数组中取出 x 个元素,使取出的元素组成的数字最大
    2. 合并两个数组,保持两数组相对位置不变,使合并后的元素组成的数字最大

    解决上面两个问题:

    1. 单调栈:从栈底到栈顶的元素单调递减,栈长度 x
    2. 从两个栈顶开始取,每次取栈顶较大的元素

    那么现在就只剩一个我们最开始设置的假设条件了,x,y (x<=k,y<=k)均是未知的,枚举从两个数组取出元素个数的所有组合,最后再第 2 步时只要保证 x+y=k,保留遇到的最大拼接结果

    【一天一大 lee】拼接最大数 (难度:困难) - Day20211202
    抛砖引玉
    /**
     * @param {number[]} nums1
     * @param {number[]} nums2
     * @param {number} k
     * @return {number[]}
     */
    var maxNumber = function(nums1, nums2, k) {
        let _result = [],
            map1 = findMax(nums1, k),
            map2 = findMax(nums2, k),
            max = 0

        // 枚举x、y的可能组合
        for (let x = 0; x <= k; x++) {
            const y = k - x
            if (x <= nums1.length && y <= nums2.length) {
                const merge = mergeMax(map1.get(x) || [], map2.get(y) || [], k)
                const num = merge.join('')
                if (num > max) {
                    max = num
                    _result = merge
                }
            }
        }
        // 1. 单调栈:从数组重取出 x 个元素,使取出的元素组成的数字最大
        function findMax(nums, k) {
            let len = nums.length,
                map = new Map()
            if (len === 0) return map
            for (let i = 1; i <= k; i++) {
                let stack = [nums[0]]
                for (let j = 1; j < len; j++) {
                    // 新元素大于栈底元素,且后面剩余的元素大于填满本轮栈的所需个数
                    while (
                        nums[j] > stack[stack.length - 1] &&
                        len - j > i - stack.length
                    ) {
                        stack.pop()
                    }
                    if (stack.length < i) {
                        stack.push(nums[j])
                    }
                }
                // 选择个数 -> 最大组合
                map.set(i, stack)
            }
            return map
        }
        // 2. 从两个栈顶开始,每次取栈顶较大的元素
        function mergeMax(stack1, stack2, k) {
            if (!stack1 || !stack2) return stack1 || stack2
            let result = []
            while (stack1.length > 0 || stack2.length > 0) {
                if (stack1.length === 0) return [...result, ...stack2]
                if (stack2.length === 0) return [...result, ...stack1]
                if (stack1.join('') >= stack2.join('')) {
                    result.push(stack1.shift())
                } else {
                    result.push(stack2.shift())
                }
            }
            return result
        }

        return _result
    }

    博客: 前端小书童

    每天的每日一题,写的题解会同步更新到公众号一天一大 lee 栏目 欢迎关注留言

    公众号:前端小书童


    起源地下载网 » 【一天一大 lee】拼接最大数 (难度:困难) - Day20211202

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元