數據結構05(Java)-- ( 歸并排序實質,歸并排序擴展問題:小和問題)

前言

本文為本小白🤯學習數據結構的筆記,將以算法題為導向,向大家更清晰的介紹數據結構相關知識(算法題都出自🙌B站馬士兵教育——左老師的課程,講的很好,對于想入門刷題的人很有幫助👍)

上面講了歸并排序,這個思想非常好??(用了遞歸來降低時間復雜度),這里我想再寫寫歸并排序的實質,以及用這個思想來解決一些問題。

??首先來看看歸并排序是怎么實現排序的

package DiGui;public class hhhguibing {public static void process(int[] arr,int L,int R){if (L==R) {return;}int mid=L + ((R-L)>>1);process(arr,L,mid);process(arr,mid+1,R);merge(arr,L,mid,R);}public static void merge(int[] arr,int L,int mid,int R){int[] help=new int[R-L+1];int i=0,p1=L,p2=mid+1;while(p1<=mid&&p2<=R){help[i++]=arr[p1]<arr[p2]?arr[p1++]:arr[p2++];}while(p1<=mid){help[i++]=arr[p1++];}while(p2<=R){help[i++]=arr[p2++];}for (i=0; i < help.length; i++) {arr[L+i]=help[i];}}
}
1.🧩先來解析一下代碼結構
public static void process(int[] arr, int L, int R)

這是遞歸函數,負責“分”的過程。

  • L 和 R 表示當前處理的區間 [L, R]。

    • 遞歸處理左半部分:process(arr, L, mid)
    • 遞歸處理右半部分:process(arr, mid+1, R)

最后調用 merge(arr, L, mid, R) 把左右兩部分合并成有序的

public static void merge(int[] arr, int L, int mid, int R)
  • 合并兩個有序數組

    • 因為有前面的遞歸過程,到merge時, [L, mid] 是有序的,[mid+1, R] 也是有序的
    • 創建一個輔助數組 help,用來暫存合并后的結果
    • 用兩個指針 p1 和 p2 分別指向左右兩個有序區的開頭
    • 比較 arr[p1] 和 arr[p2],把較小的放進 help,對應指針后移
    • 一方遍歷完后,把另一方剩下的元素全部復制過去
      最后把 help 中排好序的內容寫回原數組 arr[L…R]
💡三、舉個例子說明過程

假設數組是:[4, 1, 3, 2]

初始:[4, 1, 3, 2]↓ 分[4, 1]     [3, 2]↓           ↓[4] [1]     [3] [2]   ← 到底了,開始合并↓           ↓[1,4]       [2,3]   ← 合并兩個有序對↓ 合并[1,2,3,4]         ← 排序完成

🤔那為什么歸并排序比普通的排序時間復雜度更低呢?

🌟 核心思想:避免重復的無效比較

一、來看看傳統排序(O(n2))的“時間浪費”在哪?
插入排序為例子:

數組: [5, 4, 3, 2, 1]插入 4:要和 5 比較一次,移動 5
插入 3:要和 45 比較,移動 45
插入 2:要和 345 比較,移動 345
插入 1:要和 2345 比較,移動全部

👉 每個新元素都要從后往前逐個比較,平均要比較 O(n) 次,總共 n 個元素 → 總時間 O(n2)

  • 插入排序…等:每一步只“推進”一個元素的位置,過程中做了大量重復且低效的比較和移動。
  • 歸并排序:通過 分治 + 合并有序數組 的方式,讓每一次比較都“更有價值”。

🌏歸并排序擴展問題:

1.小和問題:
在一個數組中,每一個數左邊比當前數小的數累加起來,叫做這個數組的小和。求一個數組的小和。
例子:[1,3.4.2.5]1左邊比1小的數,沒有:3左邊比3小的數,1;4左邊比4小的數,1、3; 2左邊比2小的數,1;5左邊比5小的數,1、3、4、2;所以小和為1+1+3+1+1+3+4+2=16

為了更直觀的來看,用遞歸方法解小和問題更高效,我先寫(O(n2))的暴力解法

public static int smallSum (int[] arr) {int sum = 0;for (int i = 1; i < arr.length; i++) {for (int j = 0;j < i;j++) {if (arr[j] < arr[i]) {sum += arr[j];}}}return sum;
}        

🚀 高效解法:利用 歸并排序 → O(n log n)

先解釋一下 :

這個是把小和問題先轉化了一下,將原問題(每一個數左邊比當前數小的數累加起來),轉化為每個數右邊有幾個比它大,就說明這個數本身,被累加了幾次。
例子:[1,3.4.2.5]1右邊比1大的數,有4個:3右邊比3大的數,有2個;4右邊比4大的數,有1個; 2右邊比2大的數,有1個;5右邊比5大的數,沒有;所以小和為1 * 4+3 * 2+4 * 1+2 * 1+5 * 0=16;

那么我們只需要統計每個數右邊有幾個比它大,就可以了

public static void process(int [] arr,int L,int R) {if (L ==R ) {return 0;}int mid = L + ((R-L)>>1);return process(arr , L,mid) + process(arr , mid+1, R) + merge(arr,L,mid,R);
}public static int merge(int[] arr,int L,int mid,int R){int help=new int [R-L+1];int i=0,p1=L,p2=mid+1;int res=0;//記錄小和數while(p1<=mid&&p2<=R){res+=arr[p1] <arr[p2] ? (r-p2+1) * arr[p1] : 0;help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];}while(p1<=mid) {help[i++] = arr[p1++];}while(p2<=r) {help[i++] = arr[p2++];}for( i=0;i<help.length;i++) {arr[L +i] = help[i];}return res;
}

逆序對問題:
逆序對問題在一個數組中,左邊的數如果比右邊的數大,則這兩個數構成一個逆序對,請打印所有逆序對數。

這道題一樣的,剛才小和問題是求每個數右邊有幾個比它大,這個是求每個數右邊有幾個比它小

public static void process(int [] arr,int L,int R) {if (L ==R ) {return 0;}int mid = L + ((R-L)>>1);return process(arr , L,mid) + process(arr , mid+1, R) + merge(arr,L,mid,R);
}public static int merge(int[] arr,int L,int mid,int R){int help=new int [R-L+1];int i=0,p1=L,p2=mid+1;int res=0;//記錄小和數while(p1<=mid&&p2<=R){res+=arr[p1] > arr[p2] ? (r-p2+1) * arr[p1] : 0;help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];}while(p1<=mid) {help[i++] = arr[p1++];}while(p2<=r) {help[i++] = arr[p2++];}for( i=0;i<help.length;i++) {arr[L +i] = help[i];}return res;
}

小白啊!!!寫的不好輕噴啊🤯如果覺得寫的不好,點個贊吧🤪(批評是我寫作的動力)

…。。。。。。。。。。。…請添加圖片描述

…。。。。。。。。。。。…

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

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

相關文章

稅務專業人員能力構建與發展路徑指南

CDA數據分析師證書含金量高&#xff0c;適應了未來數字化經濟和AI發展趨勢&#xff0c;難度不高&#xff0c;行業認可度高&#xff0c;對于找工作很有幫助。一、稅務專業人員的核心能力框架能力維度關鍵技能要素專業工具與方法論實踐輸出成果稅務法規應用稅種政策解讀、法規更新…

Linux中rsync使用與inotify實時同步配置指南

Linux中rsync使用與inotify實時同步配置指南 一、rsync 簡介 rsync&#xff08;Remote Sync&#xff09;是 Linux 系統下的一款高效數據鏡像和備份工具&#xff0c;用于在本地或遠程同步文件和目錄。 支持本地復制、基于 SSH 的遠程同步&#xff0c;以及使用自有 rsync 協議的同…

Unicode 字符串轉 UTF-8 編碼算法剖析

&#x1f4ca; Unicode 字符串轉 UTF-8 編碼算法剖析 ——從 C# char 到 C wchar_t 的編碼轉換原理 引用&#xff1a;UTF-8 編解碼可視化分析 &#x1f50d; 1. 算法功能概述 該函數將 Unicode 字符串&#xff08;C# string&#xff09;轉換為 UTF-8 編碼的字節數組&#xf…

php的安全性到底怎么樣

PHP作為一種流行的服務器端腳本語言&#xff0c;被廣泛應用于Web開發。然而&#xff0c;由于PHP是一種較為靈活的語言&#xff0c;其安全性議題一直備受爭議。在這篇文章中&#xff0c;我將從多個方面來討論PHP的安全性&#xff0c;包括常見的安全漏洞、防范措施以及最佳實踐。…

mapbox高階,結合threejs(threebox)添加建筑glb模型,添加陰影效果,設置陰影顏色和透明度

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言 1.1 ??mapboxgl.Map 地圖對象 1.2 ??mapboxgl.Map style屬性 1.3 ??threebox loadObj加載模型 二、??…

SSM從入門到實戰:1.6 Spring數據訪問與JDBC模板

&#x1f44b; 大家好&#xff0c;我是 阿問學長&#xff01;專注于分享優質開源項目解析、畢業設計項目指導支持、幼小初高的教輔資料推薦等&#xff0c;歡迎關注交流&#xff01;&#x1f680; 06-Spring數據訪問與JDBC模板 &#x1f4d6; 本文概述 本文是SSM框架系列Spri…

下一代IT服務管理:ITIL5會是什么樣?

ITIL4發布到現在也就5年多時間&#xff0c;按照以往的更新節奏&#xff0c;ITIL5最早也得2027年之后。但現在IT發展的速度&#xff0c;跟以前完全不是一個量級。AI都快把我們的飯碗搶了&#xff08;開個玩笑&#xff09;&#xff0c;ITIL要是還按部就班&#xff0c;估計真要被時…

最新研究進展:2023-2025年神經機器翻譯突破性成果

文章目錄 一、模型架構創新 1.1 混合架構的崛起 1.2 多模態翻譯的突破 1.3 大語言模型與NMT的深度融合(2023-2024) 1.4 非自回歸翻譯(NAT)的效率革命(2024) 二、數據與訓練策略優化 2.1 低資源語言翻譯的飛躍 2.2 動態數據增強技術 三、效率與部署 3.1 模型壓縮與加速 3.…

OpenTelemetry WebSocket 監控終極方案:打通最后一公里

概述 OpenTelemetry&#xff0c;以下簡稱 OTEL&#xff0c;是由 CNCF 托管的“一站式可觀測性標準”&#xff0c;把指標、鏈路、日志三大信號統一為單一 SDK/API&#xff0c;零侵入地采集從瀏覽器、移動端到后端、容器、云服務的全棧遙測數據&#xff0c;并支持 40 后端一鍵導…

VS Code 出現的 Web 視圖加載錯誤和服務工作者注冊失敗問題解決方案

針對 VS Code 或 Cursor &#xff08;vscode系&#xff09;中出現的 Web 視圖加載錯誤和服務工作者注冊失敗問題&#xff0c;以下是永久性解決方案的完整操作指南&#xff1a;解決方案步驟打開命令面板 使用快捷鍵 CtrlShiftP&#xff08;Windows/Linux&#xff09;或 CmdShift…

【qml-4】qml與c++交互(類型多例)

背景&#xff1a; 【qml-1】qml與c交互第一次嘗試&#xff08;實例注入&#xff09; 【qml-2】嘗試一個有模式的qml彈窗 【qml-3】qml與c交互第二次嘗試&#xff08;類型注冊&#xff09; 【qml-4】qml與c交互&#xff08;類型多例&#xff09; 【qml-5】qml與c交互&#…

圖數據庫如何構筑 Web3 風控防線 聚焦批量注冊與鏈上盜轉 悅數圖數據庫

隨著 Web3 生態的不斷演進&#xff0c;鏈上風險呈現出團伙化、隱蔽化和動態化的趨勢&#xff0c;傳統的單點風控手段已難以應對復雜多變的攻擊模式。尤其在批量注冊薅羊毛與鏈上交易盜轉洗錢等高頻風險場景中&#xff0c;攻擊者往往通過偽造身份、跨鏈操作、多層嵌套轉賬等方式…

恒流源電路學習

恒流源的設計原理&#xff1a; 如圖所示你可以看到右邊的的推到公式得到紅點處的電壓是一個和左邊相關的定值&#xff0c;所以呢右邊的電流就是電壓除以那個4Ω&#xff0c;所以得到右邊的電路的電流大體是一個定值&#xff0c;不管你再加什么東西都可以保持這個電流&#xff…

基于生成對抗網絡的模糊圖像恢復原理與技術實現

1. 引言圖像模糊是數字圖像處理中的常見問題&#xff0c;其成因包括相機抖動、物體運動、聚焦不良等。傳統方法如維納濾波、Lucy-Richardson 算法等依賴于模糊核估計和逆濾波&#xff0c;在復雜場景下性能有限。生成對抗網絡&#xff08;Generative Adversarial Networks, GAN&…

【Doris 系列】Doris IP 變更修復

FE 恢復 異常日志 查看 fe.out 會有以下報錯&#xff0c;此時 fe 進程是無法啟動的&#xff0c;操作前注意備份所有 fe 的元數據并停止上游讀寫動作&#xff01; java.io.IOException: the self host 192.168.31.78 does not equal to the host in ROLE file 192.168.31.81. Yo…

安卓14系統應用收不到開機廣播

安卓14系統應用收不到開機廣播 - Wesley’s Blog 前段時間有測試反饋在安卓14 上面某系統應用恢復出廠設置后沒有自啟動&#xff0c;究竟是什么原因呢&#xff1f; 回顧 Android 從3.1開始&#xff0c;會將新安裝并且從未被啟動的應用置為“STOPPED”狀態&#xff0c;或者被…

C# Attribute 方法擴展

場景 剛寫完一個干凈利落的方法&#xff0c;比如保存數據到數據庫&#xff0c;邏輯清晰、結構優雅&#xff0c; 第二天&#xff0c;“嘿&#xff0c;保存完數據&#xff0c;記得給客戶發個郵件哦~” 第三天&#xff0c;“能不能再發個消息通知其他系統&#xff1f;” 第四天&am…

【URP】[法線貼圖]為什么主要是藍色的?

【從UnityURP開始探索游戲渲染】專欄-直達 法線貼圖呈現藍紫色調&#xff08;尤其以藍色為主&#xff09;是由其?存儲原理、切線空間坐標系設計及顏色編碼規則共同決定的?。 核心原因&#xff1a;法線向量的存儲規則? ?法線向量的物理范圍? 法線是單位向量&#xff0c;…

驅動開發系列63 - NVIDIA 開源GPU驅動open-gpu-kernel-modules編譯調試

目錄 一:通過apt方式安裝nvidia 驅動 二:通過 .run 方式安裝nvidia驅動 三:編譯安裝nvidia開源內核驅動 四:驗證和調試 五:卸載驅動 1. 以apt方式安裝nvidia 驅動的卸載方法 2. 以.run方式安裝nvidia驅動的卸載方法 六:安裝CUDA環境 一:通過apt方式安裝nvidia 驅動…

對KingbaseES架構的解析:從讀寫分離到異地災備的技術實現與保障機制

聲明&#xff1a;文章為本人真實測評博客&#xff0c;非廣告&#xff0c;并沒有推廣該平臺 &#xff0c;為用戶體驗文章 本人旨在分享最真實的用戶體驗&#xff0c;為關注此類產品的朋友們提供一個客觀的參考。 文章目錄一、架構全景&#xff1a;四級高可用構建數字基礎1.1 物…