每周一道算法題(十三)

本周的算法題難度級別“Medium”,用了我三天工作之余的時間,總算過了,效率較低

題目:給你一串?dāng)?shù)字,在9宮格鍵盤上輸入這串?dāng)?shù),需要求所有可能得到的字符串

分析:題目其實就是手機(jī)的九宮格輸入法,把按鍵的字母進(jìn)行排列組合即可。明確了題目,下面就來實現(xiàn)本道題

  • 確定行數(shù)和列數(shù)

我們可以發(fā)現(xiàn),列數(shù)其實就是你輸入數(shù)字的個數(shù),行數(shù)就是數(shù)字代表字母個數(shù)的乘積

  • 確字每行每列顯示的字母

我發(fā)現(xiàn)的規(guī)律是:第一列的字母是你輸入的第一個數(shù)字所代表的字母的循環(huán),第二列是第二個數(shù)字對應(yīng)字母的循環(huán)。。。最后一列循環(huán)的次數(shù)是最后一列字母的個數(shù)/最后一列字母的個數(shù),倒數(shù)第二列的循環(huán)次數(shù)是(倒數(shù)第二列字母的個數(shù) * 倒數(shù)第一列字母的個數(shù))/倒數(shù)第二列字母的個數(shù),倒數(shù)第三列的循環(huán)次數(shù)是(倒數(shù)第三列字母的個數(shù) * 倒數(shù)第二列字母的個數(shù) * 倒數(shù)第一列字母的個數(shù))/倒數(shù)第三列字母的個數(shù)。。。

通過以上的兩個規(guī)則我們就能把這道題搞定了,由于這兩個規(guī)則不好理解,我們先舉個例子來理解下這兩條規(guī)則,假設(shè)我們輸入了2?3?4三個數(shù)字,則排列組合如下圖:

通過第一條規(guī)則來確字行數(shù)和列數(shù):2代表a/b/c三個字母,3代表d/e/f三個字母,4代表g/h/i三個字母,則行數(shù)為3*3*3=27行,輸入了三個數(shù)字,所以列數(shù)為3
通過第二條規(guī)則來確定字母:我們先看最后一列,循環(huán)次數(shù)是3/3=1,即只循環(huán)一次,則直接g-h-i的循環(huán)填序即可,看倒數(shù)第二列,循環(huán)次數(shù)是(3*3)/3=3,循環(huán)3次,則按照d-d-d,e-e-e,f-f-f循環(huán)填序即可,倒數(shù)第三列的循環(huán)次數(shù)是(3*3*3)/3=9,循環(huán)9次,即9個a,9個b,9個c的循環(huán)填序即可。思路上實現(xiàn)以后,我們就用代碼來實現(xiàn):
char** letterCombinations(char* digits, int* returnSize) {
    //列數(shù)就是輸入數(shù)字的個數(shù)
    int column = (int)strlen(digits);
    //str用于存儲輸入數(shù)字所對應(yīng)的字母
    char **str = malloc(column * sizeof(char *));
    //如果輸入的個數(shù)為0
    if (column == 0) {
        *returnSize = 0;
        return str;
    }
    //通過計算每個數(shù)字所對應(yīng)字母的個數(shù)的乘積來求出行數(shù)
    int row = 1;
    for (int i = 0;i < column; i++) {
        int num =  (int)(digits[i] - '0');
        if (num == 0) str[i] = " ";
        else if (num == 1) str[i] = "*";
        else if (num == 2) str[i] = "abc";
        else if (num == 3) str[i] = "def";
        else if (num == 4) str[i] = "ghi";
        else if (num == 5) str[i] = "jkl";
        else if (num == 6) str[i] = "mno";
        else if (num == 7) str[i] = "pqrs";
        else if (num == 8) str[i] = "tuv";
        else if (num == 9) str[i] = "wxyz";
        row *= (int)strlen(str[i]);
    }
    //result為結(jié)果
    char **result = malloc(row * sizeof(char *));
    for (int i = 0; i < row; i++) 
        result[i] = malloc(column+1);
    //為result填充字母
    for (int c = column - 1; c >= 0; c--) {
        //確定循環(huán)次數(shù)temp
        int temp = c,sum = 1;
        while (temp <= column - 1) {
            sum *= strlen(str[temp]);
            temp++;
        }
        temp = sum / strlen(str[c]);
        //按列填充字母
        int r = 0;
        while (r < row) {
            result[r][c] = str[c][r/temp%strlen(str[c])];
            r++;
        }
        //填充結(jié)束符'\0'
        if (c == 0) {
            int r = 0;
            while (r < row) {
                result[r][column] = '\0';
                r++;
            }
        }
    }
    //返回結(jié)果
    *returnSize = row;
    return result;
}

這道題用了一天多的空閑時間就總結(jié)出了規(guī)律,思路一直沒錯(應(yīng)該不是最優(yōu)思路),但代碼實現(xiàn)卻花了我近兩天的時間,不得不嘆息想法和做法之間還是有一些距離,代碼實現(xiàn)中主要的問題是內(nèi)存問題,著實的被strlen這個函數(shù)坑了好久,又被'\0'這個坑坑了半天,也使得我對指針、c語言內(nèi)存機(jī)制等方面又有了新的認(rèn)識,看來光有想法還不夠,程序猿就要多敲代碼,將想法落地才能更好的成長,做出來了也是有成就感的。。。

版權(quán)聲明:本文為 Crazy Steven 原創(chuàng)出品,歡迎轉(zhuǎn)載,轉(zhuǎn)載時請注明出處!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,983評論 6 537
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,772評論 3 422
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,947評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,201評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,960評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,350評論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,406評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,549評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,104評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,914評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,089評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,647評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,340評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,753評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,007評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,834評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,106評論 2 375

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