leetcode刷题笔记321题 拼接最大数

leetcode刷题笔记321题 拼接最大数

地址:321. 拼接最大数

问题描述:

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

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

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

示例 1:

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

输入:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
输出:
[6, 7, 6, 0, 4]
示例 3:

输入:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
输出:
[9, 8, 9]

object Solution {
    def maxNumber(nums1: Array[Int], nums2: Array[Int], k: Int): Array[Int] = {
        val n = nums1.length
        val m = nums2.length
        var res = Array.fill(k)(Int.MinValue)

        //用于枚举nums中k个按照字典序的数组
        def maxArray(nums: Array[Int], k: Int): Array[Int] = {
            val res = Array.fill(k)(0)
            //println(res.mkString)
            val length = nums.length
            var j = 0
            for (i <- 0 to length-1) {
                val x = nums(i)
                while (j > 0 && res(j-1) < x && j + length - i > k) j -= 1
                //这里注意检查合法性
                if (j < k) {
                   res(j) = x
                   j += 1 
                }
            }
            return  res
        }

        //用于对总数为k的a b两数组按照字典序进行合并
        def merge(a: Array[Int], b: Array[Int]): Array[Int] = {
            var i = 0
            var j = 0
            val res = Array.fill(k)(0)
            while (i < a.length && j < b.length) {
                if (a(i) > b(j)){
                    res(i+j) = a(i)
                    i += 1
                } else if (a(i) < b(j)){
                    res (i+j) = b(j)
                    j += 1
                } else {
                    //这里是对于 == 情况的处理
                    //使用k标记最多多少位相同
                    //同时判断是否有数组被访问完
                    var k = 0
                    while (i + k < a.length && j + k < b.length && a(i+k) == b(j+k)){
                        k += 1
                    }
                   if (i + k == a.length) {
                        res (i+j) = b(j)
                        j += 1
                   } else if (j + k == b.length) {
                        res(i+j) = a(i)
                        i += 1
                   } else if (a(i+k) < b(j+k)) {
                        res (i+j) = b(j)
                        j += 1
                   } else {
                        res(i+j) = a(i)
                        i += 1
                   }
                }
            }
			//对未进行合并的结果进行合并
            while (i < a.length) {
                res(i+j) = a(i)
                i += 1
            }

            while (j < b.length) {
                res(i+j) = b(j)
                j += 1
            }
            return res
        }

        def max(a: Array[Int], b: Array[Int]): Array[Int] = {
            val length = a.length
            for (i <- 0 to length-1) {
                if (a(i) > b(i)) {
                    return a
                } else if (a(i) < b(i)) {
                    return b
                }
            }
            return a
        }

        for (i <- math.max(0, k-m) to math.min(k, n)) {
            val a = maxArray(nums1, i)
            val b = maxArray(nums2, k-i)
            //println("-----------------")
            //println("a: " + a.mkString(" "))
            //println("b: " + b.mkString(" "))
            val c = merge(a,b)
            //println("c: " + c.mkString(" "))
            res = max(res, c)
            //println("res: " + res.mkString(" "))
        }
        return res
    }
}
//import "fmt"
func maxNumber(nums1 []int, nums2 []int, k int) []int {
    n := len(nums1)
    m := len(nums2)
    res := make([]int, k)
    
    for i := max(0, k-m); i <= min(k, n); i++ {
        a := maxArray(nums1, i)
        b := maxArray(nums2, k-i)
        c := merge(a, b)
        if greater(res, c) == false {
            res = c
        }
    } 
    
    return res
}

func maxArray(nums []int, k int) []int {
    length := len(nums)
    res := make([]int, k)
    for i, j := 0, 0; i < length; i++ {
        x := nums[i]
        for (j > 0 && res[j-1] < x && j + length - i > k) {j -= 1}
        if j < k {
            res[j] = x
            j += 1
        }
    }
    return res
}

func merge(a, b []int) []int {
    length := len(a) + len(b)
    res := make([]int, length)
    i, j := 0, 0
    for k := range res {
        if greater(a[i:], b[j:]){
            res[k] = a[i]
            i += 1
        } else {
            res[k] = b[j]
            j += 1
        }
    }
    return res
}

func greater(a, b []int) bool {
     min_len := len(a)
    if len(b) < min_len {
        min_len = len(b)
    } 
    for i := 0; i < min_len; i++ {
        if a[i] > b[i] {
            return true
        } 
        if a[i] < b[i] {
            return false
        }
    }
    return min_len == len(b)
}

func max (a, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

func min (a, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}
原文地址:https://www.cnblogs.com/ganshuoos/p/14125880.html