leadcode的Hot100系列--17. 電話號碼的字母組合--回溯的另一種應用

来源:https://www.cnblogs.com/payapa/archive/2019/07/05/11136052.html
-Advertisement-
Play Games

提交leetcode的時候遇到了問題,一直說訪問越界,但仔仔細細檢查n多遍,就是檢查不出來。 因為我用到了count全局變數,自加一來表明當前數組訪問的位置, 後來突然想到,是不是在運行的時候沒有對這個全局變數清零…… 果然,清零之後就可以了……已經3:47了,這裡先上代碼,明天再詳細說吧…… ch ...


提交leetcode的時候遇到了問題,一直說訪問越界,但仔仔細細檢查n多遍,就是檢查不出來。
因為我用到了count全局變數,自加一來表明當前數組訪問的位置,
後來突然想到,是不是在leetcode在運行測試用例的時候,是連續測試的,用的同一個上下文,這樣的話,就沒有對這個全局變數清零……
果然,清零之後就可以了……已經3:47了,這裡先上代碼,明天再詳細說吧……


今天更新一下這道題的思路。
可以先參考一下之前的兩篇文章,循序漸進,好理解一些:
leadcode的Hot100系列--78. 子集--位運算
leadcode的Hot100系列--78. 子集--回溯

子集--回溯 的文章裡面,介紹了一下數字的排列組合,用01來表示對應的數字是否存在。
如果我們還是按照這個思路,但是換一個想法呢?
0、1是不是本身就可以代表著字元串?
對應排列出來的000\001\010 ... 是不是就是相當於:
我需要一個數字組合,組合需要三位數,每一位的數字要麼是0,要麼是1
這麼一想,是不是就與題目一致了:
我需要一個字母組合,組合的位數就是輸入的字元串長度,每一位的字母是對應的幾個字母中的某一個
對,就是這麼想的,比如,輸入“89”,就說明,字母組合的位數是兩位,第一位字母是'tuv'裡面的一個,第二位字母是'wxyz'裡面的一個。
這裡再看下之前上一篇中回溯的代碼:

void backtrack (int t)
{
    if (t == level)
        show();
    else  
        for (int i=0;i<=1;i++)
        {
            y[t]=i; 
            backtrack(t+1);
        }
}

重點來了!!!!

  • 第三行的level表示層數,也就是遍歷的深度,也就是組合所需要的位數,當需要兩位字母的時候,就只要兩層。
  • 第六行的for迴圈,表示了每一層的選項,之前因為只需要表示存在和不存在,所以只需要用0和1就夠了,但在這裡,是由數字對應的字元串的某一個,例如如果數字是8,則對應的選項就是't'和'u'和'v'。

所以,當輸入為“89”的時候,就可以生成這樣一種樹:

控制了樹的層數和樹的分支(分支就是可選項)之後,就可以完成所有組合。

char table[][5] = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
char level = 0;
char *p[8];   // 指向數字對應的字元串,例如,當輸入數字為"89"時,p[0]為"tuv",p[1]為"wxyz"。
char len[8];  // 對應上面p存儲的字元串的長度,例如,當輸入數字為"89"是,len[0]=3,len[1]=4。
char **out; //二維數組,是最終輸出
int count = 0; // 用來記錄當前已經生成了幾個組合,對應著out數組的行坐標
char y[8] = {0}; // 記錄每一次的組合結果

void backtrack(int level_now)
{
    if (level_now == level)
    {
        memcpy(out[count], y, level);  // 把這次組合結果拷貝到out數組中。這裡為什麼需要用一個y數組來記錄組合結果,然後拷貝到out中呢?大家可以自己想一想
        count ++;   // 完成一個字元串
        return;
    }
    for (int i=0; i<len[level_now]; i++)
    {
        y[level_now] = p[level_now][i];
        backtrack(level_now+1);
    }
    return;
}

char ** letterCombinations(char * digits, int* returnSize){
    level = strlen(digits);  // 遍歷的層數
    *returnSize = 0;
    if (0 == level) return NULL;
    
    *returnSize = 1;
    
    for(int i=0; i<level; i++)
    {
        p[i] = table[digits[i]-'0'];  // 對p數組進行賦值
        len[i] = strlen(p[i]);
        if (len[i] == 0)
        {
            *returnSize = 0;
            return NULL;
        }
        *returnSize *= len[i];    // 計算總共有多少個組合
    }
    out = (char **)calloc(*returnSize, sizeof(char *));  // 先分配行指針
    if (NULL == out) return NULL;
    for (int i=0; i<*returnSize; i++)
    {
        out[i] = (char *)calloc(1, sizeof(char) * (level+1));  // 再分配每個行指針的內容,因為字元串後面需要一個結束符'\0',所以這裡需要level+1
        if (NULL == out[i]) return NULL;
    }
    backtrack(0);
    count = 0;   // 這裡很重要!很重要!!很重要!!!
    return out;
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 郵箱核心業務場景: 發郵件 收郵件 查看郵件 郵箱業務我們關註的核心信息 草稿箱 收件箱 已發送郵件 未讀郵件 重要郵件 垃圾郵件 已刪除郵件 核心領域模型文字版 共三個模型,如下: 草稿郵件(DraftMail,聚合根): ID 標題 內容 所屬Owner郵箱地址 創建時間 支持場景:創建郵件(但 ...
  • 一個類如何表示 1. 第一格為類名 2. 第二格為類中欄位屬性 格式: 許可權:private、public 、protected、default,它們分別對應 、+、 、~ 3. 第三格為類的方法 格式: 返回類型可選 類之間的關係 多看幾次上圖,對比如下簡短說明,再結合實踐,相信你很快就可以搞清楚 ...
  • Web Service技術在我第一次接觸,又沒有實際使用時完全不理解這是什麼。以為是一種類似Spring,Shiro的編程框架。後來漸漸理解,WS(即Web Service縮寫)是一種通用的介面規範,並按照該規範編寫介面對外提供服務。 ...
  • 一、簡介 在使用mybatis時我們需要重覆的去創建pojo類、mapper文件以及dao類並且需要配置它們之間的依賴關係,比較麻煩且做了大量的重覆工作,mybatis官方也發現了這個問題, 因此給我們提供了mybatis generator工具來幫我們自動創建pojo類、mapper文件以及dao ...
  • 1. 為什麼是Spring Cloud Gateway 一句話,Spring Cloud已經放棄Netflix Zuul了。現在Spring Cloud中引用的還是Zuul 1.x版本,而這個版本是基於過濾器的,是阻塞IO,不支持長連接。Zuul 2.x版本跟1.x的架構大一樣,性能也有所提升。既然 ...
  • ​ 1.python的歷史 python2和python3的區別 python2 源碼不統一,重覆代碼 python 源碼統一,沒有重覆代碼 2004 Django框架的誕生 2.python是編程語言 3.python的種類 4.變數 變數定義的規則: 一個變數名在記憶體中只有一個。 5.常量 變數 ...
  • 一、Redis集群簡介 1、RedisCluster概念 Redis的分散式解決方案,在3.0版本後推出的方案,有效地解決了Redis分散式的需求,當一個服務宕機可以快速的切換到另外一個服務。redis cluster主要是針對海量數據+高併發+高可用的場景。 二、與SpringBoot2.0整合 ...
  • 下載地址 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...