【算法】Create Maximum Number 創(chuàng)建最大數(shù)

題目

Given two arrays of length m and n with digits 0-9 representing two numbers. Create the maximum number of length k <= m + n from digits of the two. The relative order of the digits from the same array must be preserved. Return an array of the k digits.

Note: You should try to optimize your time and space complexity.

Example 1:

Input:
nums1 = [3, 4, 6, 5]
nums2 = [9, 1, 2, 5, 8, 3]
k = 5
Output:
[9, 8, 6, 5, 3]

Example 2:

Input:
nums1 = [6, 7]
nums2 = [6, 0, 4]
k = 5
Output:
[6, 7, 6, 0, 4]

Example 3:

Input:
nums1 = [3, 9]
nums2 = [8, 9]
k = 3
Output:
[9, 8, 9]

有兩個整數(shù)數(shù)組 nums1 nums2 背率,元素值范圍是 0 ~ 9唇辨,給出 k <= nums1.count + nums2.count居灯。
創(chuàng)建一個長度為 k 的整數(shù)數(shù)組 res,使之符合以下條件:

  1. res 的元素取自 nums1 和 nums2
  2. res 的元素間相對位置與在 nums1 nums2 中的相對位置是保持不變的
  3. 多種組合中取值最大的 res

解題思路

基本思路是在 nums1 中取出 i 個值胎撇,在 nums2 中取出 k-i 個值,然后進(jìn)行合并。

  1. i 的范圍為 max(0, k-nums2.count) ... min(k, nums1.count),循環(huán)遍歷比較得最大的結(jié)果返回
  2. 循環(huán)中:
    • filterNums將 nums1 和 nums2 進(jìn)行篩選歹叮,分別得出 i 和 k-i 個值
      • 遍歷 nums跑杭,聲明臨時 res
      • es 的尾元素與 nums 中的當(dāng)前元素 num 比較,若尾元素較小盗胀,則循環(huán)將 res 中小于 num 的尾元素艘蹋,直到尾元素不小于 num锄贼,或 res 與 nums 剩余元素個數(shù)等于 k
    • mergeArray將篩選出來的值進(jìn)行合并
      • nums1 nums2 篩選出來的整數(shù)數(shù)組為 newNums1 newNums2
      • isLarger比較 newNums1[i,newNums1.count] 和 newNums2[j,newNums2.count]票灰,將較大者的當(dāng)前值加入到結(jié)果中
  3. isLarger判斷 nums1[i,nums1.count] 是否大于 nums2[i,nums2.count]
    • 循環(huán)有效的 i j ,且 nums1[i] == nums2[j] 時宅荤,i 和 j +1

    • 循環(huán)結(jié)束后的情況:

      • nums1 nums2 均沒有遍歷完屑迂,此時比較 nums1[i] > nums2[j]
      • nums1 nums2 其中任意一個遍歷完,另一個沒有遍歷完冯键,沒有遍歷完的數(shù)組較大
      • nums1 nums2 均遍歷完惹盼,結(jié)果相等
    • j == nums2.count 判斷 nums2 是否遍歷完,

      • 若 nums2 遍歷完惫确,nums1 也遍歷完手报,則相等返回 true ,覆蓋了情況 3
      • 若 nums2 遍歷完改化,nums1 沒有遍歷完掩蛤,則 nums1 大返回 true,覆蓋了情況 2
    • i < nums1.count && nums1[i] > nums2[j] 則覆蓋了情況 1

    • 所以 return j == nums2.count || (i < nums1.count && nums1[i] > nums2[j])

詳情請看代碼注釋

代碼實現(xiàn)

Runtime: 340 ms
Memory: 21.1 MB

func maxNumber(_ nums1: [Int], _ nums2: [Int], _ k: Int) -> [Int] {
        //初始化結(jié)果的容器 res
        var res = [Int]()
        //確定循環(huán)范圍陈肛,以 nums1 為基準(zhǔn)揍鸟,k-nums2.count 為 nums1 需要取的最少個數(shù),為了篩除負(fù)數(shù)句旱,與 0 取較大值
        //nums1 取的最多個數(shù)即為 k 和 nums1.count 的較小值
        for i in max(0, k-nums2.count) ... min(k, nums1.count) {
            // 將 nums1 nums2 篩選 i k-i 個元素獲得新數(shù)組 newNums1 newNums2
            let newNums1 = self.filterNums(nums: nums1, k: i)
            let newNums2 = self.filterNums(nums: nums2, k: k-i)
            // 將 newNums1 newNums2 進(jìn)行合并阳藻,獲取臨時最大數(shù)組 tmp
            let tmp = self.mergeArray(nums1: newNums1, nums2: newNums2)
            print(newNums1,newNums2,i,k)
            // 將 tmp 與 res 進(jìn)行比較,若 tmp 較大谈撒,則替換掉 res
            if self.isLarger(nums1: tmp, nums2: res, i: 0, j: 0){
                res = tmp
            }
        }
        return res
    }
    
    //將 nums 篩選 k 個元素腥泥,獲取最大數(shù)組
    func filterNums( nums: [Int],  k: Int) -> [Int]{
        // k 的邊界值處理
        if k<=0 {
            return []
        }else if k >= nums.count{
            return nums
        }
        //初始化結(jié)果的容器 res
        var res = [Int]()
        //遍歷 nums
        for i in 0 ..< nums.count{
            //獲取當(dāng)前數(shù)值 num
            let num = nums[i]
            //若 res 里的尾元素小于 num,并且 res.count + nums.count - i > k
            // res.count + nums.count - i > k 表示 res 的元素數(shù)量加上 nums 剩余的元素數(shù)量大于 k 啃匿,這樣才可以繼續(xù)刪除尾元素
            while !res.isEmpty && num > res.last! && res.count + nums.count - i > k {
                res.removeLast()
            }
            //將 num 加入到 res
            res.append(num)
        }
        //移除多余的元素
        res.removeLast(res.count-k)
        // 返回結(jié)果
        return res
    }
    
    //將兩個數(shù)組合并成最大數(shù)組
    func mergeArray(nums1: [Int], nums2: [Int]) -> [Int] {
        //初始化結(jié)果的容器 res
        var res = [Int]()
        //初始化 nums1 nums2 的序號 i j 為 0
        var i = 0 , j = 0
        //共遍歷 nums1.count + nums2.count 次
        for _ in 0 ..< nums1.count + nums2.count {
            //比較 nums1[i,nums1.count] 和 nums2[j,nums2.count]
            //將較大數(shù)組的當(dāng)前元素添加到 res蛔外,移動序號 i 或者 j
            if self.isLarger(nums1: nums1, nums2: nums2, i: i, j: j) {
                res.append(nums1[i])
                i += 1
            }else{
                res.append(nums2[j])
                j += 1
            }
        }
        //返回結(jié)果
        return res
    }
    
    //判斷 nums1 是否大于 nums2
    func isLarger(nums1: [Int], nums2: [Int], i : Int, j : Int) -> Bool {
        var i = i , j = j
        //循環(huán)有效的 i j ,且 nums1[i] == nums2[j] 時立宜,i j +1
        while i < nums1.count && j < nums2.count && nums1[i] == nums2[j] {
            i += 1
            j += 1
        }
        //循環(huán)結(jié)束后的情況:
        //1. nums1 nums2 均沒有遍歷完冒萄,此時比較 nums1[i] > nums2[j]
        //2. nums1 nums2 其中任意一個遍歷完,另一個沒有遍歷完橙数,沒有遍歷完的數(shù)組較大
        //3. nums1 nums2 均遍歷完尊流,結(jié)果相等
        
        // j == nums2.count 判斷 nums2 是否遍歷完,
        //若 nums2 遍歷完灯帮,nums1 也遍歷完崖技,則相等返回 true 逻住,覆蓋了情況 3
        //若 nums2 遍歷完,nums1 沒有遍歷完迎献,則 nums1 大返回 true瞎访,覆蓋了情況 2
        //i < nums1.count && nums1[i] > nums2[j] 則覆蓋了情況 1
        return j == nums2.count || (i < nums1.count && nums1[i] > nums2[j])
    }

代碼地址:https://github.com/sinianshou/EGSwiftLearning

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吁恍,隨后出現(xiàn)的幾起案子扒秸,更是在濱河造成了極大的恐慌,老刑警劉巖冀瓦,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伴奥,死亡現(xiàn)場離奇詭異,居然都是意外死亡翼闽,警方通過查閱死者的電腦和手機(jī)拾徙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來感局,“玉大人尼啡,你說我怎么就攤上這事⊙ⅲ” “怎么了崖瞭?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拓提。 經(jīng)常有香客問我读恃,道長,這世上最難降的妖魔是什么代态? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任寺惫,我火速辦了婚禮,結(jié)果婚禮上蹦疑,老公的妹妹穿的比我還像新娘西雀。我一直安慰自己,他們只是感情好歉摧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布艇肴。 她就那樣靜靜地躺著,像睡著了一般叁温。 火紅的嫁衣襯著肌膚如雪再悼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天膝但,我揣著相機(jī)與錄音冲九,去河邊找鬼。 笑死跟束,一個胖子當(dāng)著我的面吹牛莺奸,可吹牛的內(nèi)容都是我干的丑孩。 我是一名探鬼主播,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼灭贷,長吁一口氣:“原來是場噩夢啊……” “哼温学!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起甚疟,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤仗岖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后古拴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體箩帚,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年黄痪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片盔然。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡桅打,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愈案,到底是詐尸還是另有隱情挺尾,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布站绪,位于F島的核電站遭铺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏恢准。R本人自食惡果不足惜魂挂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馁筐。 院中可真熱鬧涂召,春花似錦、人聲如沸敏沉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盟迟。三九已至秋泳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間攒菠,已是汗流浹背迫皱。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留要尔,地道東北人舍杜。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓新娜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親既绩。 傳聞我的和親對象是個殘疾皇子概龄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容

  • <center>#51 N-Queens</center> link Description:The n-quee...
    鐺鐺鐺clark閱讀 982評論 0 0
  • 如果每天做一道算法題,那是不是每天都在進(jìn)步饲握? 前言 這個活動是從2019年7月中旬開始的私杜,人數(shù)不算多,也就幾個好友...
    雞湯小弟閱讀 302評論 0 2
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,694評論 0 3
  • 最近正在找實習(xí)救欧,發(fā)現(xiàn)自己的算法實在是不能再渣渣衰粹,在網(wǎng)上查了一下,發(fā)現(xiàn)大家都在刷leetcode的題笆怠,于是乎本渣渣也...
    caoxian閱讀 893評論 0 2
  • 一蹬刷、Adapter class FruitAdapter: ArrayAdapter{ constructor(c...
    izhenyue閱讀 253評論 0 0