演算法思想——分治演算法

来源:https://www.cnblogs.com/Cubemen/archive/2019/08/27/11421008.html
-Advertisement-
Play Games

一、分治策略 “分而治之”,大問題能夠拆成相似的小問題,記住這些小問題需要具有相似性。而後將小問題的每個解合成為大問題的解。所以說大問題如何拆,小問題如何合併才是這個演算法最主要的一個思想。實際上很多演算法如貪心演算法,動態規劃等等都是要求把大問題拆成小問題。而分治演算法的重要一點就是要適用於能夠重新把小問 ...


一、分治策略

  “分而治之”,大問題能夠拆成相似的小問題,記住這些小問題需要具有相似性。而後將小問題的每個解合成為大問題的解。所以說大問題如何拆,小問題如何合併才是這個演算法最主要的一個思想。實際上很多演算法如貪心演算法,動態規劃等等都是要求把大問題拆成小問題。而分治演算法的重要一點就是要適用於能夠重新把小問題的解合併為大問題的解。

 

二、分治法適用條件

  1、該問題的規模縮小到一定程度就可以很容易解決;

  2、該問題可以分解為若幹個規模較小的相同問題,這裡註意是最優子結構性質;

  3、利用該問題分解出的子問題的解可以合併為該問題的解;

  4、該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共子問題;

  對於很多演算法而言,第一條往往是必要的,因為數據量一旦大起來,問題往往複雜度上升的特別快。這裡就需要將這個大問題分解為小問題。小問題處理起來更加方便。第二、三條的才是分治思想的核心,因為很多時候我們會採用遞歸的方式進行解決,所以在大問題分解為小問題的時候需要保證小問題之間的相同性。單單分解為小問題之後還不能算完成,必須要能夠將小問題的解合併為這個問題的最終解才能算真正用到了分治的思想。最後一條也是最關鍵的,各個子問題之間必須要保證獨立性,即不互相影響。如果相互之間有影響,這時候我們採用的是動態規劃就更加好一點。

三、例題

  其實演算法的思想不用講太多,能夠化為幾句話是最好的,下麵就舉幾個例子來看看分治演算法:

  例題一:二分查找,給定一個按照升序排好的數組array,要在這個數組中找出一個特定的元素x;

  當我們遇到一個問題,完全可以在心裡問自己下麵四個問題:

  1、當前問題能不能切分?

  答:能切分,因為數組按照升序來排列。所以當x大於某個元素array[mid]時,x一定在array[mid]的右邊。以此再來切分。每次切一半

  2、分解出來的子問題相同嗎?

  答:相同,每個子問題的數據集都是父問題的1/2倍。並且每次只比較子問題的中間的數據

  3、子問題的解能合併為父問題的解嗎?

  答:不需要合併,子問題的解即為父問題的解。

  4、子問題之間相互獨立嗎?

  答:獨立,子問題只是判斷,不需要和父問題有很強的關聯性(這裡可以參考一下動態規划算法,就能理解子問題之間怎麼判斷是獨立的)

public class Main{
  public int BinarySearch(int[] array,int x,int left,int right){

        while(left<=right){
            int mid=(left+right)/2;
            if(array[mid]==x){
                return mid;
            }
            if(array[mid]>x)right=mid-1;
            else left=mid+1;
        }
        return -1;
    } 
}

  例題二:歸併排序,給定一個無序數組array[7]={49,38,65,97,76,13,27},使其變的有序

  同樣在自己心裡問問4個問題

  1、當前問題能切分嗎?

  答:能,最簡單的就是兩個數之間的比較,這個數組可以看成多個兩個數來比較

  2、分解出來的子問題是否相同?

  答:相同,都是兩個數比較大小。

  3、子問題的解能夠合成父問題的解嗎?

   答:每兩個有序數組再按照一定順序合起來就是最終的題解。這裡就是有個合併的過程

  4、子問題之間相互獨立嗎?

  答:獨立,分到最小的時候子問題之間互不影響。

  下麵是歸併排序代碼:

public class MergeSort {

    public static void merge(int[] arr,int l,int mid,int r){
        int[] aux= Arrays.copyOfRange(arr,l,r+1);
        int i=l,j=mid+1;
        for(int k=l;k<r;k++){
            if(i>mid){
                arr[k]=aux[j-l];
                j++;
            }
            else if(j>r){
                arr[k]=aux[i-l];
                i++;
            }
            else if(aux[i-l]<aux[j-l]){
                arr[k]=aux[i-l];i++;
            }
            else {
                arr[k]=aux[j-l];j++;
            }
        }

    }
    // 遞歸使用歸併排序,對arr[l...r]的範圍進行排序
    public static void sort(int[] arr, int l, int r) {

        if (l >= r)
            return;

        int mid = (l+r)/2;
        sort(arr, l, mid);
        sort(arr, mid + 1, r);
        merge(arr, l, mid, r);
    }
}

  歸併的示意圖如下:

 

 

  最後問題來了,快速排序是用了分治演算法的思想嗎?

四、總結

  分治演算法只是一種思想,不是一個具體的套路,只能說在碰見具體問題時我們能夠從這個思路去思考,切分問題?合併問題?子問題之間影響關聯大不大?這些都是具體問題具體考慮。還有很多很多題目是用了分治演算法。也可以多刷刷題


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

-Advertisement-
Play Games
更多相關文章
  • 題目鏈接: https://pintia.cn/problem-sets/994805260223102976/problems/994805260990660608 分析: 這是典型的給出編號和得分然後輸出最高分和最低分的題目,只不過得分要通過x和y計算得到。 本人利用字元數組存放運動員的編號,這 ...
  • 1.創建虛擬環境 2.進入虛擬環境 3.創建項目 4.創建資料庫 5.創建應用 6.查看項目 瀏覽器輸入:127.0.0.1:8000即可查看 ...
  • 工具類,是一個單獨的工程項目 提取必要信息至ftp.properties配置文件中 封裝FtpUtils工具類 導入jar包版本: 測試調用: 註:使用的是springboot,已經集成了ftp,所以沒有配置相應的xml文件。 ...
  • hashlib模塊 用於加密相關的操作,3.x里代替了md5模塊和sha模塊 加密功能 運行結果(將hello轉換成一個密文): ...
  • SQLite是一款輕型的資料庫,是遵守ACID的關係型資料庫管理系統。 不像常見的客戶-伺服器範例,SQLite引擎不是個程式與之通信的獨立進程,而是連接到程式中成為它的一個主要部分。所以主要的通信協議是在編程語言內的直接API調用。 Python標準庫包含一個SQLite包裝器:使用模塊sql... ...
  • 最近培訓新人,最後練習使用Struts2框架練習,但是聯繫中碰到了畫面List對象傳後臺無法傳遞的問題。網上看了一圈沒有找到對應的解決辦法。最後自己找到了一種,寫下來後面可以再看。 註:方法千千萬,有其他能解決的,或者我寫的有不對的地方歡迎指正! 上圖表格裡面的就是我想上傳到後臺的內容,因為下麵的更 ...
  • 電腦與程式設計 1.根據一系列指令對數據進行處理的工具或機器 (編程語言) 2.特征: 2.1可以進行數據計算 2.2 根據指令執行任務 3.組成 3.1運算器+控制器(CPU) 3.2存儲器(記憶體及硬碟)——>記憶體:臨時;硬碟:永久 3.3輸入設備和輸出設備 4.工作過程(IPO) 4.1輸入( ...
  • ACM-Jesus Is Here[遞推]2015沈陽online ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...