Coursera Algorithms week3 歸併排序 練習測驗: Counting inversions

来源:http://www.cnblogs.com/evasean/archive/2017/07/24/7230996.html
-Advertisement-
Play Games

題目原文: An inversion in an array a[] is a pair of entries a[i] and a[j] such that i<j but a[i]>a[j]. Given an array, design a linearithmic algorithm to ...


題目原文:

An inversion in an array a[] is a pair of entries a[i] and a[j] such that i<j but a[i]>a[j]. Given an array, design a linearithmic algorithm to count the number of inversions.

分析:

如果沒有性能限制,用插入排序演算法可以實現。題目性能被限制在nlogn,又是歸併排序的練習題,很顯然要實現個歸併排序,併在裡面計數。通過一個例子來看下計數方法,例如{6, 5, 2, 3, 4, 1}這個序列,歸併過程中會分為分為如下幾步:

1. 歸併{6, 5},存在一次右側元素5移至左側的操作,變成{5, 6},歸併前逆序對<6,5>

2. 歸併{5, 6, 2},存在一次右側元素2移至左側的操作, 變成{2, 5, 6},歸併前存在兩對逆序對<5, 2>和<6, 2>

3. 歸併{3, 4},不存在右側元素左移操作

4. 歸併{3, 4, 1},存在一次右側元素1移至左側的操作,變成{1, 3, 4},歸併前存在兩對逆序對<3, 1>和<4, 1>

5. 歸併{2, 5, 6, 1, 3, 4},存在三次1、3、4右側元素移至左側的操作,歸併前存在七對逆序對<2,1><5,1><6,1><5,3><6,3><5,4><6,4>

由上述分析可見,當右側元素a[j]與左側元素a[i]進行比較後需要移至左側時,a[j]與區間 [ a[i] , a[mid] ]中的所有元素都可以組成逆序對,這個區間的元素個數為mid+1-i個。

因此代碼如下:

 1 import java.util.Arrays;
 2 
 3 /**
 4  * @author evasean www.cnblogs.com/evasean/
 5  */
 6 public class CountInversions {
 7     private static Comparable[] aux;
 8     private static int num = 0; // 逆序對計數
 9 
10     private static boolean less(Comparable v, Comparable w) {
11         return v.compareTo(w) < 0;
12     }
13 
14     public static int inversionsNum(Comparable[] a) {
15         aux = new Comparable[a.length];
16         sort(a, 0, a.length - 1);
17         return num;
18     }
19 
20     private static void sort(Comparable[] a, int lo, int hi) {
21         if (hi <= lo)
22             return;
23         int mid = lo + (hi - lo) / 2;
24         sort(a, lo, mid);
25         sort(a, mid + 1, hi);
26         merge(a, lo, mid, hi);
27     }
28 
29     private static void merge(Comparable[] a, int lo, int mid, int hi) {
30         int i = lo;
31         int j = mid + 1;
32         for (int k = lo; k <= hi; k++) {
33             aux[k] = a[k];
34         }
35         for (int k = lo; k <= hi; k++) {
36             if (i > mid)  // i>mid表示aux的左半側已經被全部被放於a中,直接將右半側部分放入a
37                 a[k] = aux[j++];
38             else if (j > hi) // j>hi表示aux的右半側已經被全部被放於a中,直接將左半側部分放入a
39                 a[k] = aux[i++]; 
40             else if (less(aux[j], aux[i])){ // 右側元素小於左側元素時,將右側元素放入
41                 num += mid+1-i; //此時右側的這個元素a[j]和[a[i],a[mid]]整個區間的元素都是逆序對
42                 a[k] = aux[j++];
43             }else a[k] = aux[i++];
44         }
45         //System.out.println(Arrays.toString(a));
46     }
47 
48     public static void main(String[] args) {
49         Integer[] a = { 6,5,2,3,4,1 };
50         System.out.println(inversionsNum(a));
51         System.out.println(Arrays.toString(a));
52     }
53 }

 


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

-Advertisement-
Play Games
更多相關文章
  • 知乎的整個網站架構圖如下: 知乎是國內很少的使用Python開發的一個網站,也很多值得我們學習的地方,從知乎讓我們也可以瞭解到一些新的WEB技術。 一、Python框架 知乎目前使用的是Tornado 框架。Tornado 全稱Tornado Web Server,是一個用Python 語言寫成的W ...
  • 一 log4j log4j是Apache的一個開源項目,用於輸出程式的運行狀況。 相比於在程式內部添加System.out.println()做日誌輸出,log4j有如下優點: 可以設定信息輸出的目的地,常用的有控制台、文件等。 根據日誌的嚴重程度,將日誌分為6級,從高到低依次是:fatal、err ...
  • 消息保證送達是指消息發送方保證在任何情況下都會至少一次確定的消息送達。AtleastOnceDelivery是一個獨立的trait,主要作用是對不確定已送達的消息進行補發,這是一種自動的操作,無需用戶干預。既然涉及到消息的補發,就不可避免地影響發送方和接收方之間消息傳遞的順序、接收方重覆收到相同的消 ...
  • 1、函數嵌套 1.1函數的嵌套調用 在調用一個函數的過程中,又調用了其他函數 1.2函數的嵌套定義 在一個函數的內部,又定義另外一個函數 2、名稱空間 2.1名稱空間 名稱空間:存放名字的地方,準確的說名稱空間是存放名字與變數值綁定關係的地方 內置名稱空間:在python解釋器啟動時產生,存放一些p ...
  • 一 概述 1.整合目的 有了Spring以後,所有對象的創建任務都應該交給Spring容器來完成,這樣做不僅是為了降低代碼的耦合度,而且可以利用Spring容器作為代理工廠實現代理。 2.整合目標 將Spring容器中的bean註入Action中,將Action的創建與管理工作交給Spring容器。 ...
  • 一 概述 1.整合目的 將所有對象的創建與管理任務交給Spring容器,降低程式的耦合度。 2.整合途徑 將Spring容器註入到Web容器中。 3.具體實現 使用ServletContextListener監聽ServletContext,當ServletContexxt創建時同時創建Spring ...
  • 經典數據集CIFAR-10,60000張32x32彩色圖像,訓練集50000張,測試集10000張。標註10類,每類圖片6000張。airplance、automobile、bird、cat、deer、dog、frog、horse、ship、truck。沒有任何重疊。CIFAR-100,100類標註 ...
  • 載入MNIST數據集。創建預設Interactive Session。 初始化函數,權重製造隨機雜訊打破完全對稱。截斷正態分佈雜訊,標準差設0.1。ReLU,偏置加小正值(0.1),避免死亡節點(dead neurons)。 捲積層函數,tf.nn.conv2d,TensorFlow 2 維捲積函數 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...