leetcode刷題筆記321題 拼接最大數
阿新 • • 發佈:2020-12-12
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 } }