【Leetcode 每日一題】2545. 根據第 K 場考試的分數排序

問題背景

班里有 m m m 位學生,共計劃組織 n n n 場考試。給你一個下標從 0 0 0 開始、大小為 m × n m \times n m×n 的整數矩陣 s c o r e score score,其中每一行對應一位學生,而 s c o r e [ i ] [ j ] score[i][j] score[i][j] 表示第 i i i 位學生在第 j j j 場考試取得的分數。矩陣 s c o r e score score 包含的整數 互不相同
另給你一個整數 k k k。請你按第 k k k 場考試分數從高到低完成對這些學生(矩陣中的行)的排序。
返回排序后的矩陣。

數據約束

  • m = s c o r e . l e n g t h m = score.length m=score.length
  • n = s c o r e [ i ] . l e n g t h n = score[i].length n=score[i].length
  • 1 ≤ m , n ≤ 250 1 \le m, n \le 250 1m,n250
  • 1 ≤ s c o r e [ i ] [ j ] ≤ 105 1 \le score[i][j] \le 105 1score[i][j]105
  • s c o r e score score不同 的整數組成
  • 0 ≤ k < n 0 \le k \lt n 0k<n

解題過程

根據某個標準帶著整個數組排序,可以當作模板記下來。
題目保證待排序的元素不重復,那就可以完全不考慮穩定性的問題。
寫一下在其它算法中常用 O ( N l o g N ) O(NlogN) O(NlogN) 量級的簡單做法,再把三種常用排序都實現一下當作練習好了。

具體實現

調用 API

class Solution {public int[][] sortTheStudents(int[][] score, int k) {Arrays.sort(score, (o1, o2) -> o2[k] - o1[k]);return score;}
}

歸并排序 - 遞歸版

class Solution {// 二維數組最大長度為 250,開長為 300 的輔助數組就夠了private static final int MAX_N = 300;private static final int[][] temp = new int[MAX_N][];private int k;public int[][] sortTheStudents(int[][] score, int k) {this.k = k;mergeSort(score, 0, score.length - 1);return score;}// 歸并操作,入參改成二維數組private void merge(int[][] arr, int left, int mid, int right) {int index1 = left, index2 = mid + 1, index = left;while(index1 <= mid && index2 <= right) {// 除了收集元素的標準不一樣,其它都可以不變temp[index++] = arr[index1][k] > arr[index2][k] ? arr[index1++] : arr[index2++];}while(index1 <= mid) {temp[index++] = arr[index1++];}while(index2 <= right) {temp[index++] = arr[index2++];}System.arraycopy(temp, left, arr, left, right - left + 1);}// 歸并排序,入參改成二維數組private void mergeSort(int[][] arr, int left, int right) {if(left == right) {return;}int mid = left + ((right - left) >>> 1);mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
}

歸并排序 - 非遞歸版

class Solution {// 二維數組最大長度為 250,開長為 300 的輔助數組就夠了private static final int MAX_N = 300;private static final int[][] temp = new int[MAX_N][];private int k;public int[][] sortTheStudents(int[][] score, int k) {this.k = k;mergeSort(score);return score;}// 歸并操作,入參改成二維數組private void merge(int[][] arr, int left, int mid, int right) {int index1 = left, index2 = mid + 1, index = left;while(index1 <= mid && index2 <= right) {// 除了收集元素的標準不一樣,其它都可以不變temp[index++] = arr[index1][k] > arr[index2][k] ? arr[index1++] : arr[index2++];}while(index1 <= mid) {temp[index++] = arr[index1++];}while(index2 <= right) {temp[index++] = arr[index2++];}System.arraycopy(temp, left, arr, left, right - left + 1);}// 歸并排序,入參改成二維數組private void mergeSort(int[][] arr) {int n = arr.length;for(int left, mid, right, step = 1; step < n; step <<= 1) {left = 0;while(left < n) {mid = left + step - 1;if(mid >= n - 1) {break;}right = Math.min(left + (step << 1) - 1, n - 1);merge(arr, left, mid, right);left = right + 1;}}}
}

隨機快速排序

class Solution {private int k;public int[][] sortTheStudents(int[][] score, int k) {this.k = k;quickSort(score, 0, score.length - 1);return score;}// 交換操作,入參改成二維數組private void swap(int[][] arr, int i, int j) {int[] temp = arr[i];arr[i] = arr[j];arr[j] = temp;}public static int first, last;// 隨機快排,入參改成二維數組private void quickSort(int[][] arr, int left, int right) {if (left >= right) {return;}int pivot = arr[left + (int) (Math.random() * (right - left + 1))][k];partition(arr, left, right, pivot);quickSort(arr, left, first - 1);quickSort(arr, last + 1, right);}// 劃分操作,入參改成二維數組public void partition(int[][] arr, int left, int right, int pivot) {first = left;last = right;int cur = left;while (cur <= last) {if (arr[cur][k] == pivot) {cur++;// 修改區域標準,較大的數往數組左側交換} else if (arr[cur][k] > pivot) {swap(arr, first++, cur++);} else {swap(arr, cur, last--);}}}
}

堆排序

class Solution {private int k;public int[][] sortTheStudents(int[][] score, int k) {this.k = k;heapSort(score);return score;}// 交換操作,入參改成二維數組private void swap(int[][] arr, int i, int j) {int[] temp = arr[i];arr[i] = arr[j];arr[j] = temp;}private void downAdjust(int[][] arr, int cur, int size) {int child = 2 * cur + 1;while (child < size) {// 修改確定修改目標的條件,用小根堆來完成排序,就能得到從大到小的結果int target = child + 1 < size && arr[child + 1][k] < arr[child][k] ? child + 1 : child;target = arr[target][k] < arr[cur][k] ? target : cur;if (target == cur) {break;}swap(arr, target, cur);cur = target;child = 2 * cur + 1;}}// 建堆操作,入參改成二維數組private void buildHeap(int[][] arr) {int n = arr.length;for (int i = n - 1; i >= 0; i--) {downAdjust(arr, i, n);}}// 堆排序,入參改成二維數組private void heapSort(int[][] arr) {buildHeap(arr);int size = arr.length;while (size > 0) {swap(arr, 0, --size);downAdjust(arr, 0, size);}}
}

總結梳理

Java 中的排序 API 的實現是 Tim Sort,大體上可以理解為在數據量較小的情況下使用 插入排序,通常使用歸并排序。這里表現出來的效率不如直接實現的歸并排序,猜想是因為整體數據量不是很大,在某些樣例上被忽悠使用了效率不是那么高的算法。
歸并排序 能夠保證時間復雜度在 O ( N l o g N ) O(NlogN) O(NlogN) 這個量級的同時,算法本身是穩定的,是有必要自己實現排序算法時的首選,只需要考慮開輔助數組會不會影響效率。
快速排序 不僅需要額外的系統棧空間,還不穩定。它有時會成為面試時手撕算法的考題,需要好好掌握。
堆排序 是一種原地算法,但是不穩定,所以通常不是一個好的排序算法的選擇。但是堆本身能夠維護一系列元素中的最大值或者最小值,是一種非常好用的數據結構。

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

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

相關文章

React系列(八)——React進階知識點拓展

前言 在之前的學習中&#xff0c;我們已經知道了React組件的定義和使用&#xff0c;路由配置&#xff0c;組件通信等其他方法的React知識點&#xff0c;那么本篇文章將針對React的一些進階知識點以及React16.8之后的一些新特性進行講解。希望對各位有所幫助。 一、setState &am…

PCIe_Host驅動分析_地址映射

往期內容 本文章相關專欄往期內容&#xff0c;PCI/PCIe子系統專欄&#xff1a; 嵌入式系統的內存訪問和總線通信機制解析、PCI/PCIe引入 深入解析非橋PCI設備的訪問和配置方法 PCI橋設備的訪問方法、軟件角度講解PCIe設備的硬件結構 深入解析PCIe設備事務層與配置過程 PCIe的三…

【閱讀記錄-章節6】Build a Large Language Model (From Scratch)

文章目錄 6. Fine-tuning for classification6.1 Different categories of fine-tuning6.2 Preparing the dataset第一步&#xff1a;下載并解壓數據集第二步&#xff1a;檢查類別標簽分布第三步&#xff1a;創建平衡數據集第四步&#xff1a;數據集拆分 6.3 Creating data loa…

ip_output函數

ip_output函數是Linux內核(特別是網絡子系統)中用于發送IPv4數據包的核心函數。以下是一個示例實現,并附上詳細的中文講解: int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) {struct iphdr *iph; /* 構建IP頭部 */iph = ip_hdr(skb);/* 設置服務…

梳理你的思路(從OOP到架構設計)_簡介設計模式

目錄 1、 模式(Pattern) 是較大的結構?編輯 2、 結構形式愈大 通用性愈小?編輯 3、 從EIT造形 組合出設計模式 1、 模式(Pattern) 是較大的結構 組合與創新 達芬奇說&#xff1a;簡單是複雜的終極形式 (Simplicity is the ultimate form of sophistication) —Leonardo d…

用SparkSQL和PySpark完成按時間字段順序將字符串字段中的值組合在一起分組顯示

用SparkSQL和PySpark完成以下數據轉換。 源數據&#xff1a; userid,page_name,visit_time 1,A,2021-2-1 2,B,2024-1-1 1,C,2020-5-4 2,D,2028-9-1 目的數據&#xff1a; user_id,page_name_path 1,C->A 2,B->D PySpark&#xff1a; from pyspark.sql import SparkSes…

【libuv】Fargo信令2:【深入】client為什么收不到服務端響應的ack消息

客戶端處理server的ack回復,判斷鏈接連接建立 【Fargo】28:字節序列【libuv】Fargo信令1:client發connect消息給到server客戶端啟動后理解監聽read消息 但是,這個代碼似乎沒有觸發ack消息的接收: // 客戶端初始化 void start_client(uv_loop_t

硬盤dma讀寫過程

pci初始化時&#xff0c;遍歷pci上的設置&#xff0c;如果BaseClassCode1&#xff0c;則為大容量存儲控制器&#xff0c;包括硬盤控制器、固態硬盤控制器、光盤驅動控制器、RAID控制器等。 BaseAdder4為DMA控制器基地址&#xff0c;包含兩個控制器&#xff0c;主控制器&#x…

Python-基于Pygame的小游戲(貪吃蛇)(一)

前言:貪吃蛇是一款經典的電子游戲&#xff0c;最早可以追溯到1976年的街機游戲Blockade。隨著諾基亞手機的普及&#xff0c;貪吃蛇游戲在1990年代變得廣為人知。它是一款休閑益智類游戲&#xff0c;適合所有年齡段的玩家&#xff0c;其最初為單機模式&#xff0c;后來隨著技術發…

使用k6進行MongoDB負載測試

1.安裝環境 安裝xk6-mongo擴展 ./xk6 build --with github.com/itsparser/xk6-mongo 2.安裝MongoDB 參考Docker安裝MongoDB服務-CSDN博客 連接成功后新建test數據庫和sample集合 3.編寫腳本 test_mongo.js import xk6_mongo from k6/x/mongo;const client xk6_mongo.new…

solon 集成 activemq-client (sdk)

原始狀態的 activemq-client sdk 集成非常方便&#xff0c;也更適合定制。就是有些同學&#xff0c;可能對原始接口會比較陌生&#xff0c;會希望有個具體的示例。 <dependency><groupId>org.apache.activemq</groupId><artifactId>activemq-client&l…

2024 年最新前端ES-Module模塊化、webpack打包工具詳細教程(更新中)

模塊化概述 什么是模塊&#xff1f;模塊是一個封裝了特定功能的代碼塊&#xff0c;可以獨立開發、測試和維護。模塊通過導出&#xff08;export&#xff09;和導入&#xff08;import&#xff09;與其他模塊通信&#xff0c;保持內部細節的封裝。 前端 JavaScript 模塊化是指…

uni-app商品搜索頁面

目錄 一:功能概述 二:功能實現 一:功能概述 商品搜索頁面,可以根據商品品牌,商品分類,商品價格等信息實現商品搜索和列表展示。 二:功能實現 1:商品搜索數據 <view class="search-map padding-main bg-base"> <view class…

最小堆及添加元素操作

【小白從小學Python、C、Java】 【考研初試復試畢業設計】 【Python基礎AI數據分析】 最小堆及添加元素操作 [太陽]選擇題 以下代碼執行的結果為&#xff1f; import heapq heap [] heapq.heappush(heap, 5) heapq.heappush(heap, 3) heapq.heappush(heap, 2) heapq.…

10. 考勤信息

題目描述 公司用一個字符串來表示員工的出勤信息 absent:缺勤late: 遲到leaveearly: 早退present: 正常上班 現需根據員工出勤信息&#xff0c;判斷本次是否能獲得出勤獎&#xff0c;能獲得出勤獎的條件如下: 缺勤不超過一次&#xff0c;沒有連續的遲到/早退:任意連續7次考勤&a…

【計算機網絡】期末考試預習復習|中

作業講解 轉發器、網橋、路由器和網關(4-6) 作為中間設備&#xff0c;轉發器、網橋、路由器和網關有何區別&#xff1f; (1) 物理層使用的中間設備叫做轉發器(repeater)。 (2) 數據鏈路層使用的中間設備叫做網橋或橋接器(bridge)。 (3) 網絡層使用的中間設備叫做路…

前端工程化-Vue腳手架安裝

在現代前端開發中&#xff0c;Vue.js已成為一個流行的框架&#xff0c;而Vue CLI&#xff08;腳手架&#xff09;則為開發者提供了一個方便的工具&#xff0c;用于快速創建和管理Vue項目。本文將詳細介紹如何安裝Vue腳手架&#xff0c;創建新項目以及常見問題的解決方法。 什么…

利用爬蟲獲取的數據能否用于商業分析?

在數字化時代&#xff0c;數據已成為企業獲取競爭優勢的關鍵資源。網絡爬蟲作為一種數據收集工具&#xff0c;能夠從互聯網上抓取大量數據&#xff0c;這些數據在商業分析中扮演著重要角色。然而&#xff0c;使用爬蟲技術獲取的數據是否合法、能否用于商業分析&#xff0c;是許…

羅德與施瓦茨ZN-Z129E網絡分析儀校準套件具體參數

羅德與施瓦茨ZN-Z129E網絡校準件ZN-Z129E網絡分析儀校準套件 1&#xff0c;頻率范圍從9kHz到4GHz&#xff08;ZNB4&#xff09;,8.5GHz(ZNB8)&#xff0c;20GHz(ZNB20)&#xff0c;40GHz(ZNB40) 2&#xff0c;動態范圍寬&#xff0c;高達140 dB 3&#xff0c;掃描時間短達4ms…

如何為IntelliJ IDEA配置JVM參數

在使用IntelliJ IDEA進行Java開發時&#xff0c;合理配置JVM參數對于優化項目性能和資源管理至關重要。IntelliJ IDEA提供了兩種方便的方式來設置JVM參數&#xff0c;以確保你的應用程序能夠在最佳狀態下運行。本文將詳細介紹這兩種方法&#xff1a;通過工具欄編輯配置和通過服…