字節(jié)KSUM一道你不知道的算法題

image

一.前言


文章主要給大家分享一個(gè)字節(jié)跳動(dòng)自己出的算法題目--KSUM。作者學(xué)習(xí)了很多,但是沒(méi)有能夠很好的解決這個(gè)問(wèn)題蝙茶,只會(huì)用暴力回溯法解決。如果你有更好的辦法诸老,歡迎評(píng)論區(qū)發(fā)布出來(lái)讓更多人看到隆夯,謝謝啦!


二. 有請(qǐng)主角--KSUM


題目

  • 請(qǐng)用算法實(shí)現(xiàn)别伏,從給定的無(wú)序蹄衷、不重復(fù)的數(shù)組data中,取出K個(gè)數(shù)厘肮,找出K數(shù)之和和與輸入的SUM相等的所有情況愧口,并使算法的時(shí)間/空間復(fù)雜度盡量的低。
var ksum = function(data, k , sum){
}
  • 思路
    對(duì)于這個(gè)題目作者可以想到的就是回溯法一步一步的嘗試結(jié)果可不可以类茂,流程如下:
  1. 給定一個(gè)無(wú)重復(fù)數(shù)組[1,2,3,4,5,7],我們輸入k為3调卑,需要返回所有sum為10的情況抡砂。
  2. 用回溯法,也就是暴力法恬涧,我來(lái)走一遍注益,首先選擇第一個(gè)數(shù),數(shù)組[1,2,3,4,5,7]中每一個(gè)數(shù)都可以被選到溯捆,如下圖:
image
  1. 第二步丑搔,我們可以以第一個(gè)數(shù)選擇1為例,第二個(gè)數(shù)就可能選擇[2,3,4,5,7]中的任何一個(gè)數(shù)提揍,如下圖:
image
  1. 第三步:選擇第三個(gè)數(shù)啤月,這里我們以已經(jīng)選擇1和2為例第三個(gè)數(shù)就只能選擇[3,4,5,7],在選擇第三數(shù)的時(shí)候劳跃,我們可以知道選擇7是我們想要的結(jié)果谎仲,返回到結(jié)果的數(shù)組中,并退回上一步去找其他情況刨仑。如果第三步中都沒(méi)有滿足的數(shù)郑诺,也退回第二步去進(jìn)行選擇查找的可能的情況,當(dāng)?shù)诙蕉紱](méi)有符合的情況杉武,就再退回第一步進(jìn)行查找直到所有的情況都遍歷完辙诞,然后返回結(jié)果。

三.書寫代碼

我們以寫js為例

上回溯模板

來(lái)自國(guó)外某大佬轻抱,凡是涉及回溯的都可以使用這個(gè)模板

/**
 * backtrack(){
 * if(){
 * //終止條件
 * }
 * 枚舉出每一步可選的列表
 *  for(){
 *   //做出選擇
 *     backtrack()
 *   // 撤銷選擇 回到上一步
 * }
 *
 * }
 */

開(kāi)始解題

  1. 初始化變量
var ksum = function(data, k , sum){
    let list = [];
    backtrack(data,list,k,sum)
    return list;
}

function backtrack(data, list, k, sum, tempList = [], start = 0){
}
  1. 對(duì)數(shù)組進(jìn)行遍歷飞涂,選擇
function backtrack(data, list, k, sum, tempList = [], start = 0){
    //tempList 已經(jīng)做過(guò)的選擇
    //for 枚舉出每一步可選的列表
    for(let i = start; i<data.length;i++){
        //數(shù)組里面每一項(xiàng)都要選擇
        tempList.push(data[i]);
        //之后的步驟
        backtrack(data, list, k, sum, tempList.slice(0), i+1)
        //tempList.slice(0)淺復(fù)制保存一下之前的結(jié)果,以防pop掉祈搜,之后返回空數(shù)組
        // 撤銷上一步選擇
        tempList.pop();
    }
}

首先做出選擇较店,且每一項(xiàng)都會(huì)被選擇,tempList暫存已經(jīng)做的選擇容燕,start初始選擇泽西,且對(duì)起始位置進(jìn)行限制(上一步走到哪里了),i+1下一步的start

  1. 終止條件
if(tempList.length === k ){
        if(tempList.reduce((a,b) => a+b,0) === sum){
            //找到
            list.push(tempList);
        }
        return;//回到上一步
    }

終止條件有兩個(gè),一是選擇的數(shù)已經(jīng)夠了等于k缰趋,二是加起來(lái)的和等于sum捧杉,如果滿足我們將暫存的數(shù)組,push到list結(jié)果里面秘血,而且不管滿不滿足都回到上一步味抖。

  1. 書寫完畢,測(cè)試
    所有代碼如下:
var ksum = function (data, k, sum) {
    let list = [];
    backtrack(data, list, k, sum)
    return list;
}

function backtrack(data, list, k, sum, tempList = [], start = 0) {
    if (tempList.length === n) {
        if (tempList.reduce((a, b) => a + b, 0) === sum) {
            list.push(tempList);
        }
        return;
    }
    for (let i = start; i < data.length; i++) {
        tempList.push(data[i]);
        backtrack(data, list, k, sum, tempList.slice(0), i + 1)
        tempList.pop();
    }
}

console.log(ksum([1, 2, 3, 4, 5, 6, 7, 8], 3, 10))

結(jié)果:

image

結(jié)果正確灰粮,書寫結(jié)束仔涩,模板真好用!U持邸熔脂!


結(jié)束

文章看到現(xiàn)在也結(jié)束啦佩研,如果有錯(cuò)誤的話就麻煩大家給我指出來(lái)吧!如果覺(jué)得不錯(cuò)的話別忘了點(diǎn)個(gè)贊??再走噢霞揉!歡迎把你想到的方法寫在評(píng)論區(qū)喔旬薯,作者想要進(jìn)步,哈哈适秩。

個(gè)人博客地址

期待

  • 作者大三正在尋找春招實(shí)習(xí)中绊序,期待大佬的青睞~
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市秽荞,隨后出現(xiàn)的幾起案子骤公,更是在濱河造成了極大的恐慌,老刑警劉巖扬跋,帶你破解...
    沈念sama閱讀 222,681評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阶捆,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡钦听,警方通過(guò)查閱死者的電腦和手機(jī)洒试,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)彪见,“玉大人儡司,你說(shuō)我怎么就攤上這事娱挨∮嘀福” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 169,421評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵跷坝,是天一觀的道長(zhǎng)酵镜。 經(jīng)常有香客問(wèn)我,道長(zhǎng)柴钻,這世上最難降的妖魔是什么淮韭? 我笑而不...
    開(kāi)封第一講書人閱讀 60,114評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮贴届,結(jié)果婚禮上靠粪,老公的妹妹穿的比我還像新娘。我一直安慰自己毫蚓,他們只是感情好占键,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著元潘,像睡著了一般畔乙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上翩概,一...
    開(kāi)封第一講書人閱讀 52,713評(píng)論 1 312
  • 那天牲距,我揣著相機(jī)與錄音返咱,去河邊找鬼。 笑死牍鞠,一個(gè)胖子當(dāng)著我的面吹牛咖摹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播皮服,決...
    沈念sama閱讀 41,170評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼楞艾,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了龄广?” 一聲冷哼從身側(cè)響起硫眯,我...
    開(kāi)封第一講書人閱讀 40,116評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎择同,沒(méi)想到半個(gè)月后两入,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡敲才,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評(píng)論 3 342
  • 正文 我和宋清朗相戀三年裹纳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片紧武。...
    茶點(diǎn)故事閱讀 40,865評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剃氧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阻星,到底是詐尸還是另有隱情朋鞍,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布妥箕,位于F島的核電站滥酥,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏畦幢。R本人自食惡果不足惜坎吻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望宇葱。 院中可真熱鬧瘦真,春花似錦、人聲如沸黍瞧。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,699評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)雷逆。三九已至弦讽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背往产。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,814評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工被碗, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仿村。 一個(gè)月前我還...
    沈念sama閱讀 49,299評(píng)論 3 379
  • 正文 我出身青樓锐朴,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蔼囊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子焚志,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評(píng)論 2 361

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

  • 在C語(yǔ)言中,五種基本數(shù)據(jù)類型存儲(chǔ)空間長(zhǎng)度的排列順序是: A)char B)char=int<=float C)ch...
    夏天再來(lái)閱讀 3,352評(píng)論 0 2
  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,238評(píng)論 0 4
  • 1.把二元查找樹(shù)轉(zhuǎn)變成排序的雙向鏈表 題目: 輸入一棵二元查找樹(shù),將該二元查找樹(shù)轉(zhuǎn)換成一個(gè)排序的雙向鏈表畏鼓。 要求不...
    曲終人散Li閱讀 3,325評(píng)論 0 19
  • 1酱酬、Kmp匹配算法:開(kāi)始的時(shí)候還是遍歷targetstring ,根據(jù)findstring的每個(gè)字符去查找云矫,這樣需...
    奪光閱讀 350評(píng)論 0 0
  • 看完電影《怦然心動(dòng)》让禀,像朱莉這樣的女孩挑社,我好像認(rèn)識(shí)一個(gè)。 小學(xué)六年級(jí)的時(shí)候巡揍,女孩特別喜歡和他用同一個(gè)書桌的那個(gè)男孩...
    小安akw閱讀 568評(píng)論 0 1