【遞歸,搜索與回溯算法 綜合練習】深入理解暴搜決策樹:遞歸,搜索與回溯算法綜合小專題(二)

??

?


優美的排列


? ? 題目解析? ??



? ? 算法原理? ??


? ? 解法? :暴搜? ??


? ? 決策樹? ??


紅色剪枝:用于剪去該節點的值在對應分支中,已經被使用的情況,可以定義一個 check[ ]


紫色剪枝:perm[i] 不能夠被 i 整除,i 不能夠被 perm[i] 整除,此時分支就要執行紫色剪枝


? ? 設計函數? ??



? ? 編寫代碼? ??



?N皇后


? ? 題目解析? ??


本題的算法原理是比較簡單的,難點在于剪枝操作和代碼實現能力;?


? ? 算法原理? ??


? ? 解法:暴搜? ??


? ? 決策樹? ??


決策樹的任務:給一個行數,每次枚舉這一行的一個格子,枚舉的格子看是否同列或者主副對角線是否有皇后,沒有則在該格子放一個皇后,并停止枚舉這一行剩下的格子,遞歸下一行;?

綠色剪枝:剪去遍歷的格子所在列,出現其他皇后的情況;

紫色剪枝:剪去遍歷的格子所在主副對角線,出現其他皇后的情況;

所以 N = 3,3皇后是沒有合法的放置方法的?;

當我們的行數為 N+1,說明已經枚舉到了一種合法的結果;


? ? 如何剪枝:考慮當前位置,能否放上皇后? ??


? ? ?策略一:無腦循環? ??


我們在遍歷到一個格子的時候,使用四個循環判斷當前格子所在行,列,左對角線,右對角線是否放有其他皇后,總體時間復雜度 O(N) = 4N * (2 ^N);雖然時間復雜度高,但是也是可以通過的

我們可以對這個方法進行優化,因為我們的決策樹是每一行的其中一個格子用來放皇后,所以行是一定不會出現皇后攻擊的情況的,所以只用看列,左對角線,右對角線是否放有其他皇后;


? ? ?策略二:類似哈希表的策略? ???


對于棋盤,我們分別定義兩個 boolean 類型的數組?row[ ],col[ ] ,用于判斷某一行或者某一列是否放置皇后;

?如果某個格子放置有皇后,對應的 row[ i ] ,col [ j ] 要置為 true ;后續再進行決策的時候,就可以先看看對應的 row,col 是否為 true,任意一個為 true 則不用再考慮本次枚舉的格子;


接下來,我們來解決主對角線和副對角線的情況;

我們通過觀察可以發現,當皇后要放置 N 個時,對應的主對角線和副對角線都是 2 * N - 1;

并且斜率分別是 1 和 -1,所以對于一條對角線,可以用y = x + b 或者 y = -x +b 來表示;

  • 對于主對角線,則有 y -? x = b ,縱坐標 + 橫坐標為一個定值;
  • 對于副對角線,則有 x + y = b , 縱坐標 - 橫坐標為一個定值;

所以我們再次定義兩個 boolean 類型的數組 ,dig1,dig2 ,分別表示主對角線和副對角線;這兩個數組的長度為 2*N ,用于存儲所有的主對角線,或者副對角線;

用 b = y - x ,b = y + x 來表示某一條對角線的映射關系,當 dig1[ b ] == true ||?dig2 [ b ] == true,則說明該格子所在對角線放有其他皇后;


但是還有一個細節問題:

對于上圖的主對角線,y - x? 是一個負數,如果直接使用 dig1 [ b ] 會越界;

解決辦法:添加上一個偏移量 n:y - x + n = b + n,讓對角線統一向上移動 n 個單位,來處理截距為負數的情況;所以針對主對角線,我們判斷的是 dig1[ b + n ] 是否是 true 即可;


? ? 編寫代碼? ??


? ? 前期初始化操作? ??



? ? ?主邏輯? ??



有效的數獨


? ? 題目解析? ??


本題并不是關于暴搜的題目,而是一個哈希表的題;我們通過講解這道題的算法原理?,為下一道題?解數獨 做好鋪墊


? ? 算法原理? ??


? ? 解法:暴搜? ??



?我們先來定義一個 boolean 類型的數組?row [ ?] [ ?]:

第一個 [ i ] 表示的是數獨表中的第 i 行, 第二個 [ j ] 表示的是在這一行有沒有出現 j 這個數字;

如:row [ 2 ][ 4 ] 表示的是第二行有沒有出現 4 這個數字,有的話 row [ 2 ][ 4 ] == true;


col[ i ][ j ] 數組同理,表示的是第 i 列是否出現了 j 這個數字?;


除了用數組來表示數度表外,我們也可以用哈希表來表示數獨表,并且用哈希表非常巧妙:

我們是以一個3 x 3 的小數獨表作為一個單位格子的,此時下標就只有 0,1,2;


我們設置一個 boolean 類型的數組 grid :?

grid [ 0 ][ 0 ] 表示左上角第一個 3x3 的大方格;


為了查看一個 3x3 的大方格所有數是否都出現過,我們再開一個空間給 grid:?


如何定義小方格和大方格下標的映射關系呢?

?當有一個元素的位置為 [ x , y ] ,映射的九宮格下標位置為 [ x/3 , y/3 ];


? ? 編寫代碼? ??



解數獨


? ? 題目解析? ??



? ? 算法原理? ??


? ? 解法 : 暴搜? ?


? ? 決策樹? ??


上圖代表決策樹的某一條分支,我們可以發現,當按照其中一條分支填到第一行最后一個格子時,第一行每使用過的最后一個元素可能是不能填入該格子中的;


那我們怎么知道這條分支的選擇不能填滿數獨表呢?在遍歷某個 ' . ' 的格子時,如果所有數都不符合題意,我們返回 false 即可;

這個代碼的報錯原因,就是沒有對【因為前面的選擇,導致某一個格子 1 到 9 都不能填入】的情況進行處理;


所以如果遇到【某一個格子 1 到 9 都不能填入】的情況,我們就應該向上返回 false,因此,我們的 dfs 應該設置 boolean 類型的返回值,告訴上一層,這種選法是否可以得到正確的數獨,如果返回 false,我們就要讓上一層的格子嘗試下一個數;

dfs 的參數其實可以直接把 board 數組傳入即可;在 dfs 中遍歷 board ,專門處理 board[ i ][ j ] == '.'? 的情況;


? ? 編寫代碼? ??


? ? 初始化? ? ?



? ? 填數邏輯? ???



? ? 攻克難點? ? ?


本題難點就是要想到 dfs 是 boolean 類型,并且要找到?dfs 中合適的位置進行返回;


? ? 對這三處 return 的解讀? ??




單詞搜索


? ? 題目解析? ??



? ? 算法原理? ??


? ? 解法 :深度優先遍歷? ?


? ? 模擬過程? ??


我們以下面這個矩陣和 word 為例子來模擬過程:?


剛開始,會先遍歷矩陣中所有的元素,直到找到word 的第一個字符 ' A?'


此時會對當前?A 的格子上下左右進行掃描,直到找到 B:


對于當前位置的 A ,上下左右位置并沒有 B ,說明這個 A 不是我們要找的 A ,我們尋找下一個 A:


此時,我們發現當前 A 的位置右邊和下方都有 B ,就需要遞歸這兩種情況:

下方的 B 上下左右查找,并沒有找到 C,我們遍歷右邊的 B?


此時的情況和上面同理:?


最終得到結果,返回 true:?

如果按照上面的模擬過程,矩陣找不到 word ,則返回 false;?


? ? 決策樹? ??



? ? 函數設計? ? ?



? ? 細節問題一:如何避免走重復路徑? ??


? ? 問題描述? ? ?



? ? 模擬過程? ??



? ? ?解決方法一: 設置一個 boolean 數組? ??


定義一個跟原始矩陣相同規模的 boolean 數組 :

用 visit 來標記當前位置,下次遍歷到某一個位置時,通過 visit 查看這個位置是否已經被使用過;


? ? ?解決方法二: 修改原始矩陣的值? ???


當我們對某一個格子進行上下左右查找,查找到下一個字符時,把這個位置修改成 ' . '?

面試的時候要問問面試官可不可以修改原始矩陣,修改原始矩陣的行為不保險;


? ? 細節問題二:用向量數組映射??( i , j ) 位置的上下左右坐標? ???


設置兩個一維數組 dx[ 4 ] , dy [ 4 ] :?


dx[ i ] 和 dy [ i?] 要能映射到同一個方向,映射關系如下:

我們使用一個 for 循環,就可以一個坐標的上下左右關系全部找到;如果要找 8 個方向,我們就定義兩個長度為 8 的數組,來表示 8 個不同的方向;這種方法在二維數組表示方向的時候,是非常好用的;


? ? 編寫代碼? ??


? ? 準備工作? ??


在主函數中,先遍歷一次矩陣,找到第一個 word[ 0 ] ,然后調用 dfs,從第一個 word[ 0 ] 所在位置開始找 word 剩下的元素;


? ? 主邏輯? ? ?



? ? 代碼細節詳解? ? ?






?模擬上述對?return? 會遇到的情況?:


黃金礦工


? ? 題目解析? ??



? ? 算法原理? ??


本題的算法原理和上一題是一類題型,解法大差不差,只是一些細節問題不同;這一題先嘗試自己編寫代碼,再根據老師的視頻改進;


? ? 解法:暴搜? ???



? ? 編寫代碼? ??



? ? 編寫歷程? ??





那么,我們什么時候在主函數更新結果呢?如果要設置遞歸出口,就要再寫一層 for 循環,判斷上下左右的 vis ==true || grid == 0,對于這道題是沒有必要設置遞歸出口的;


只需要找到一輪遞歸的最大值 tmp 即可,并且更新 ret 即可;所以我們一進入 dfs 就更新 ret


? ? 總結? ? ?

關于更新結果的問題是難點:尤其是在哪里更新結果?這么更新結果有什么用?為什么要這樣更新結果?


每次作出一題,都要想清楚這幾個問題,并且學會新的處理細節問題的方式,如:

  • 二維矩陣搜索路徑時,避免走重復路徑的方法;
  • 使用向量坐標表示一個格子不同的方向;

不同路徑Ⅲ


? ? 題目解析? ??




? ? 算法原理? ??


? ? 解法 :暴搜? ?



? ? 編寫代碼? ??



? ? 優化? ??


減少循環次數:?


? ? 繼續優化? ??


我們可以對遞歸出口進行優化,原來是只有合法路徑才 return ,現在是只要走到終點就 return:?


總結?


關于暴搜的題目,算法原理其實并不難,重點考察的就是我們的代碼能力,以及能否發現細節問題,并且對細節問題進行合理的處理;?


?

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64252.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64252.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64252.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java中各種數組復制方式的效率對比

在 Java 中,數組復制是一個常見的操作,尤其是在處理動態數組(如 ArrayList)時。Java 提供了多種數組復制的方式,每種方式在性能和使用場景上都有所不同。以下是對幾種主要數組復制方式的比較,包括 System.a…

視頻會議是如何實現屏幕標注功能的?

現在主流的視頻會議軟件都有屏幕標注功能,屏幕標注功能給屏幕分享者講解分享內容時提供了極大的方便。那我們以傲瑞視頻會議(OrayMeeting)為例,來講解屏幕標注是如何實現的。 傲瑞會議的PC端(Windows、信創Linux、銀河…

Framework開發入門(一)之源碼下載

一、使用Linux操作系統的小伙伴可以跳轉到官網鏈接按提示操作 官網源碼地址:下載源代碼 | Android Open Source Project 1.創建一個空目錄來存放您的工作文件。為其指定一個您喜歡的任意名稱: mkdir WORKING_DIRECTORYcdWORKING_DIRECTORY …

改進爬山算法之四:概率爬山法(Probabilistic Hill Climbing,PHC)

概率爬山法(Probabilistic Hill Climbing,PHC)是一種局部搜索算法,它結合了隨機性和貪婪搜索的特點,是對爬山算法(Hill Climbing Algorithm)的一種變體或擴展。與傳統的爬山法不同,PHC不是總是選擇最優的鄰居作為下一步的移動,而是以一定的概率選擇最優鄰居,同時以一…

Unity中實現人物殘影效果

今天火柴人聯盟3公測了,看到一個殘影的效果,很有意思,上網查詢了一下實現方式, 實現思路: 將角色的網格復制出來,然后放置到新建的物體的MeshFilter組件上,每隔幾十毫秒在玩家的位置生成一個&a…

C#實現調用DLL 套殼讀卡程序(桌面程序開發)

背景 正常業務已經支持 讀三代卡了,前端調用醫保封裝好的服務就可以了,但是長護要讀卡,就需要去訪問萬達,他們又搞了一套讀卡的動態庫,為了能夠掉萬達的接口,就需要去想辦法調用它們提供的動態庫方法&…

自動擋有什么優勢

自動擋汽車相比手動擋汽車具有多方面的優勢,以下是對這些優勢的詳細闡述: 一、操作簡便性 無需手動換擋:自動擋汽車不需要駕駛員手動操作離合器和換擋桿,只需通過油門和剎車踏板來控制車速,大大降低了駕駛難度。這使…

菜鳥帶新鳥——基于EPlan2022的部件庫制作(3D)

設備邏輯的概念: 可在布局空間 中和其它對象上放置對象。可將其它對象放置在 3D 對象上。已放置的對象分到組件的邏輯結構中。 將此屬性的整體標識為設備邏輯。可使用不同的功能創建和編輯設備邏輯。 設備的邏輯定義 定義 / 旋轉 / 移動 / 翻轉:組…

小程序基礎 —— 07 創建小程序項目

創建小程序項目 打開微信開發者工具,左側選擇小程序,點擊 號即可新建項目: 在彈出的新頁面,填寫項目信息(后端服務選擇不使用云服務,開發模式為小程序,模板選擇為不使用模板)&…

Android Java 版本的 MSAA OpenGL ES 多重采樣

最近多次被小伙伴問到 OpenGL 多重采樣,其實前面文章里多次講過了,就是構建2個緩沖區,多重采樣緩沖區和目標解析緩沖區。 代碼流程 // Framebuffer IDs private int msaaFBO; private int msaaColorBuffer; private int msaaDepthBuffer;pr…

Markdown語法字體字號講解

學習目錄 語法詳解改變字體樣式[電腦要自帶該樣式字體]改變局部字號全局字體字號的設置使用場景及應用實例 > 快來試試吧😃 👇 👇 👈點擊該圖片即可跳轉至Markdown學習網站進行 Markdown語法字體字號講解👈點擊這里…

Spring boot處理跨域問題

Spring boot處理跨域問題 方案一方案二推薦解決方案注意 方案一 實現WebMvcConfigurer的addCorsMappings方法 Configuration public class InterceptorConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMappin…

TOTP雙因素認證(2FA)php簡單實現

TOTP身份驗證的工作原理基于時間戳和密鑰。用戶需要在設置階段將密鑰與相應的身份驗證器進行綁定。通常,用戶會在需要使用TOTP動態驗證碼的APP或網站上獲得一個密鑰,然后將該密鑰添加到TOTP驗證器工具上。驗證器會根據當前的時間戳和密鑰生成一個一次性密…

day21——web自動化測試(3)Unittest+Selenium實戰小案例

【沒有所謂的運氣🍬,只有絕對的努力?】 目錄 今日目標: 1、UnitTest框架 2、UnitTest 核心用例 2.1 TestCase 2.2 TestSuite 2.3 TestRunner 2.4 TestLoader 2.5 TestLoader 與 TestSuite的區別 2.6 Fixture 3、斷言 3.1 1230…

【Flink運行時架構】系統構架

SMP架構 數據處理系統的架構最簡單的實現方式就是單節點,但是隨著數據量的增大,為了使單節點的機器性能更加強大,需要增加CPU數量和加大內存來提高吞吐量。這就是所謂的SMP(Symmetrical Multi Processing,對稱多處理)架構。 但是這種架構帶來…

CountDownLatch應用舉例

定義 CountDownLatch是juc下的一個多線程鎖,下面是jdk對它的定義 A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. 翻譯如下 一種同步輔助工具,允許一個或多個…

ADC(二):外部觸發

有關ADC的基礎知識請參考標準庫入門教程 ADC(二):外部觸發 1、TIM1的CC1事件觸發ADC1DMA重裝載2、TIM3的TRGO事件(的更新事件)觸發ADC1DMA重裝載3、TIM3的TRGO事件(的捕獲事件)觸發ADC1DMA重裝載4、優化TIM3的TRGO事件(的捕獲事件)觸發ADC1D…

磁盤分區格式

MBR和GPT ?磁盤分區形式主要有兩種:MBR和GPT。?? MBR(Master Boot Record) MBR是一種較舊的分區形式,首次引入于1983年的IBM PC DOS 2.0。它位于驅動器的第一個扇區,包含460字節的引導代碼、64字節的磁盤分區表和…

幾個支持用戶名密碼的代理鏈工具: glider, gost, proxychains+microsocks

幾個支持用戶名密碼的代理鏈工具: glider, gost, proxychainsmicrosocks gost -L:7777 -Fsocks5://192.168.2.20:7575 -Fsocks5://user:passwd1.1.1.1:10086 -Dgost:(https://github.com/ginuerzh/gost) 參考 https://www.quakemachinex.com/blog/279.html

量子退火與機器學習(1):少量數據求解未知QUBO矩陣,以少見多

文章目錄 前言ー、復習QUBO:中藥配伍的復雜性1.QUBO 的介入:尋找最佳藥材組合 二、難題:QUBO矩陣未知的問題1.為什么這么難? 三、稀疏建模(Sparse Modeling)1. 欠定系統中的稀疏解2. L1和L2的選擇: 三、壓縮感知算法(C…