7.優化算法之分治-快排歸并

0.分治

分而治之

1.顏色分類

75. 顏色分類 - 力扣(LeetCode)

給定一個包含紅色、白色和藍色、共?n?個元素的數組?nums?,原地對它們進行排序,使得相同顏色的元素相鄰,并按照紅色、白色、藍色順序排列。

我們使用整數?0、?1?和?2?分別表示紅色、白色和藍色。

必須在不使用庫內置的 sort 函數的情況下解決這個問題。

示例 1:

輸入:nums = [2,0,2,1,1,0]
輸出:[0,0,1,1,2,2]

示例 2:

輸入:nums = [2,0,1]
輸出:[0,1,2]

class Solution {public void sortColors(int[] nums) {int n=nums.length;int left=-1,right=n,i=0;while(i<right){//i要掃描完if(nums[i]==0){swap(nums,++left,i++);}else if(nums[i]==2){swap(nums,--right,i);}else{i++;}}}public void swap(int[] nums,int x,int y){int tmp=nums[x];nums[x]=nums[y];nums[y]=tmp;}
}

2.快速排序

排序數組

給你一個整數數組?nums,請你將該數組升序排列。

class Solution {public int[] sortArray(int[] nums) {qsort(nums,0,nums.length-1);return nums;}public void qsort(int[] nums,int l,int r){if(l>=r){return;}//數組分為三塊//1.隨機在區間內選值int key=nums[new Random().nextInt(r-l+1)+l];int left=l-1,right=r+1,i=l;while(i<right){if(nums[i]<key){swap(nums,++left,i++);}else if(nums[i]==key){i++;}else{swap(nums,--right,i);}}//[l,left],[left+1,right-1],[right,r]qsort(nums,l,left);qsort(nums,right,r);}public void swap(int[] nums,int x,int y){int tmp=nums[x];nums[x]=nums[y];nums[y]=tmp;}
}

3.數組中的第k個最大元素

215. 數組中的第K個最大元素 - 力扣(LeetCode)

給定整數數組?nums?和整數?k,請返回數組中第?k?個最大的元素。

請注意,你需要找的是數組排序后的第?k?個最大的元素,而不是第?k?個不同的元素。

你必須設計并實現時間復雜度為?O(n)?的算法解決此問題。

示例 1:

輸入: [3,2,1,5,6,4], k = 2
輸出: 5

示例?2:

輸入: [3,2,3,1,2,4,5,5,6], k = 4
輸出: 4

class Solution {public int findKthLargest(int[] nums, int k) {return qsortchoice(nums, 0, nums.length - 1, k);}public int qsortchoice(int[] nums, int l, int r, int k) {while (l == r) {return nums[l];}// 隨機在范圍內選擇對應的數字// 隨機選擇一個基準元素int key = nums[new Random().nextInt(r - l + 1) + l];// 根據基準元素,使得數組分為三部分int left = l - 1, right = r + 1, i = l;while (i < right) {if (nums[i] < key) {swap(nums, ++left, i++);} else if (nums[i] == key) {i++;} else {swap(nums, --right, i);}}// 快速選擇的算法,分情況討論int b = right - left - 1, c = r - right + 1;if (c >= k) {return qsortchoice(nums, right, r, k);} else if (b + c >= k) {return key;} else {return qsortchoice(nums, l, left, k - b - c);}}public void swap(int[] nums, int x, int y) {int tmp = nums[x];nums[x] = nums[y];nums[y] = tmp;}
}

4.最小的K個數

class Solution {public int[] inventoryManagement(int[] nums, int k) {qsortchoice(nums, 0, nums.length - 1, k);int[] ret=new int[k];for(int i=0;i<k;i++){ret[i]=nums[i];}return ret;}public void qsortchoice(int[] nums, int l, int r, int k) {while (l == r) {return;}// 隨機在范圍內選擇對應的數字// 隨機選擇一個基準元素int key = nums[new Random().nextInt(r - l + 1) + l];// 根據基準元素,使得數組分為三部分int left = l - 1, right = r + 1, i = l;while (i < right) {if (nums[i] < key) {swap(nums, ++left, i++);} else if (nums[i] == key) {i++;} else {swap(nums, --right, i);}}// 快速選擇的算法,分情況討論int a=left-l+1,b=right-1-left-1+1;if (a>k) {qsortchoice(nums, l, left, k);} else if (a + b >= k) {return;} else {qsortchoice(nums, right,r, k - a-b);}}public void swap(int[] nums, int x, int y) {int tmp = nums[x];nums[x] = nums[y];nums[y] = tmp;}
}

5.歸并排序

912. 排序數組 - 力扣(LeetCode)

在遞歸的時候如果總是需要new一個變量,這是我們可以把這個變量作為全局變量。

class Solution {int[] tmp;//定義全局變量,就不用反復new了public int[] sortArray(int[] nums) {tmp=new int[nums.length];mergeSort(nums,0,nums.length-1);return nums;}public void mergeSort(int[] nums,int left,int right){if(left>=right){return;}//1.根據中間點劃分區間int mid=(left+right)/2;//[left,mid][mid+1,right]//2.先把左右區間排個序 mergeSort(nums,left,mid);mergeSort(nums,mid+1,right);//3.合并兩個有序數組int cur1=left,cur2=mid+1,i=0;while(cur1<=mid&&cur2<=right){tmp[i++]=nums[cur1]<=nums[cur2]?nums[cur1++]:nums[cur2++];}//處理沒有遍歷完的數組while(cur1<=mid){tmp[i++]=nums[cur1++];}while(cur2<=right){tmp[i++]=nums[cur2++];}//還原到nums數組上for(int j=left;j<=right;j++){nums[j]=tmp[j-left];}}
}

6.數組中的逆序對

LCR 170. 交易逆序對的總數 - 力扣(LeetCode)

class Solution {int[] tmp;public int reversePairs(int[] record) {int n=record.length;tmp=new int[n];return mergeSort(record,0,n-1);}public int mergeSort(int[] nums,int left,int right){while(left>=right){return 0;}int ret=0;//選擇一個中間點,將數組進行劃分int mid=(left+right)/2;//[left,mid][mid+1,right]//2.左半部分的個數+右半部分的個數+排序ret=ret+mergeSort(nums,left,mid);ret=ret+mergeSort(nums,mid+1,right);//3.一左一右的個數int cur1=left,cur2=mid+1,i=0;while(cur1<=mid&&cur2<=right){if(nums[cur1]<=nums[cur2]){tmp[i++]=nums[cur1++];}else{ret=ret+mid-cur1+1;tmp[i++]=nums[cur2++];}}//4.處理一下后面的排序while(cur1<=mid){tmp[i++]=nums[cur1++];}while(cur2<=right){tmp[i++]=nums[cur2++];}for(int j=left;j<=right;j++){nums[j]=tmp[j-left];}return ret;}
}

?7.計算右側?于當前元素的個數(難點)

315. 計算右側小于當前元素的個數 - 力扣(LeetCode)

class Solution {int[] ret;int[] index; // 標記 nums 中當前元素的原始下標int[] tmpIndex;int[] tmpNums;public List<Integer> countSmaller(int[] nums) {int n = nums.length;ret = new int[n];index = new int[n];tmpIndex = new int[n];tmpNums = new int[n];// 初始化 index 數組for (int i = 0; i < n; i++) {index[i] = i;}mergeSort(nums, 0, n - 1);List<Integer> l = new ArrayList<Integer>();for (int x : ret) {l.add(x);}return l;}public void mergeSort(int[] nums, int left, int right) {if (left >= right) {return;}// 1. 根據中間元素劃分區間int mid = (left + right) / 2;// [left, mid] [mid + 1, right]// 2. 處理左右兩個區間mergeSort(nums, left, mid);mergeSort(nums, mid + 1, right);// 3. 處理?左?右的情況int cur1 = left, cur2 = mid + 1, i = 0;while (cur1 <= mid && cur2 <= right) { // 降序排序if (nums[cur1] <= nums[cur2]) {tmpNums[i] = nums[cur2];tmpIndex[i++] = index[cur2++];} else {ret[index[cur1]] += right - cur2 + 1; // 重點tmpNums[i] = nums[cur1];tmpIndex[i++] = index[cur1++];}}// 4. 處理剩余的排序?作while (cur1 <= mid) {tmpNums[i] = nums[cur1];tmpIndex[i++] = index[cur1++];}while (cur2 <= right) {tmpNums[i] = nums[cur2];tmpIndex[i++] = index[cur2++];}for (int j = left; j <= right; j++) {nums[j] = tmpNums[j - left];index[j] = tmpIndex[j - left];}}
}

?8.翻轉對

給定一個數組?nums?,如果?i < j?且?nums[i] > 2*nums[j]?我們就將?(i, j)?稱作一個重要翻轉對

你需要返回給定數組中的重要翻轉對的數量。

示例 1:

輸入: [1,3,2,3,1]
輸出: 2

示例 2:

輸入: [2,4,3,5,1]
輸出: 3

注意:

  1. 給定數組的長度不會超過50000
  2. 輸入數組中的所有數字都在32位整數的表示范圍內。

?

class Solution {int[] tmp;public int reversePairs(int[] nums) {int n = nums.length;tmp = new int[n];return mergeSort(nums, 0, n - 1);}public int mergeSort(int[] nums, int left, int right) {if (left >= right)return 0;int ret = 0;// 1. 根據中間元素,將區間分成兩部分int mid = (left + right) / 2;// [left, mid] [mid + 1, right]// 2. 求出左右兩個區間的翻轉對ret += mergeSort(nums, left, mid);ret += mergeSort(nums, mid + 1, right);// 3. 處理?左?右 - 先計算翻轉對int cur1 = left, cur2 = mid + 1, i = left;// 降序版本while (cur1 <= mid) {while (cur2 <= right && nums[cur2] >= nums[cur1] / 2.0)cur2++;if (cur2 > right)break;ret += right - cur2 + 1;cur1++;}// 4. 合并兩個有序數組cur1 = left;cur2 = mid + 1;while (cur1 <= mid && cur2 <= right)tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur2++] : nums[cur1++];while (cur1 <= mid)tmp[i++] = nums[cur1++];while (cur2 <= right)tmp[i++] = nums[cur2++];for (int j = left; j <= right; j++)nums[j] = tmp[j];return ret;}
}

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

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

相關文章

Elasticsearch (1):ES基本概念和原理簡單介紹

Elasticsearch&#xff08;簡稱 ES&#xff09;是一款基于 Apache Lucene 的分布式搜索和分析引擎。隨著業務的發展&#xff0c;系統中的數據量不斷增長&#xff0c;傳統的關系型數據庫在處理大量模糊查詢時效率低下。因此&#xff0c;ES 作為一種高效、靈活和可擴展的全文檢索…

PHP爬蟲類的使用技巧與注意事項

php爬蟲類的使用技巧與注意事項 隨著互聯網的迅猛發展&#xff0c;大量的數據被不斷地生成和更新。為了方便獲取和處理這些數據&#xff0c;爬蟲技術應運而生。PHP作為一種廣泛應用的編程語言&#xff0c;也有許多成熟且強大的爬蟲類庫可供使用。在本文中&#xff0c;我們將介…

Qt Creator 的設置文件保存位置

在使用 Qt Creator 進行開發時,備份或遷移設置(例如文本編輯器偏好、語法高亮等)是常見需求。了解這些設置文件在不同操作系統中的保存位置,可以簡化這個過程。本文將為您詳細介紹 Qt Creator 保存設置文件的位置。 默認文件位置 Qt Creator 會創建多個文件和目錄來存儲其…

springboot系列八: springboot靜態資源訪問,Rest風格請求處理, 接收參數相關注解

文章目錄 WEB開發-靜態資源訪問官方文檔基本介紹快速入門注意事項和細節 Rest風格請求處理基本介紹應用實例注意事項和細節思考題 接收參數相關注解基本介紹應用實例PathVariableRequestHeaderRequestParamCookieValueRequestBodyRequestAttributeSessionAttribute ?? 上一篇…

微服務-網關Gateway

個人對于網關路由的理解&#xff1a; 網關就相當于是一個項目里面的保安&#xff0c;主要作用就是做一個限制項。&#xff08;zuul和gateway兩個不同的網關&#xff09; 在路由中進行配置過濾器 過濾器工廠&#xff1a;對請求或響應進行加工 其中filters&#xff1a;過濾器配置…

探索QCS6490目標檢測AI應用開發(三):模型推理

作為《探索QCS6490目標檢測AI應用開發》文章&#xff0c;緊接上一期&#xff0c;我們介紹如何在應用程序中介紹如何使用解碼后的視頻幀結合Yolov8n模型推理。 高通 Qualcomm AI Engine Direct 是一套能夠針對高通AI應用加速的軟件SDK&#xff0c;更多的內容可以訪問&#xff1a…

摸魚大數據——Spark基礎——Spark環境安裝——PySpark搭建

三、PySpark環境安裝 PySpark: 是Python的庫, 由Spark官方提供. 專供Python語言使用. 類似Pandas一樣,是一個庫 Spark: 是一個獨立的框架, 包含PySpark的全部功能, 除此之外, Spark框架還包含了對R語言\ Java語言\ Scala語言的支持. 功能更全. 可以認為是通用Spark。 功能 P…

Golang | Leetcode Golang題解之第199題二叉樹的右視圖

題目&#xff1a; 題解&#xff1a; /** 102. 二叉樹的遞歸遍歷*/ func levelOrder(root *TreeNode) [][]int {arr : [][]int{}depth : 0var order func(root *TreeNode, depth int)order func(root *TreeNode, depth int) {if root nil {return}if len(arr) depth {arr a…

線性代數--行列式1

本篇來自對線性代數第一篇的行列式的一個總結。 主要是行列式中有些關鍵點和注意事項&#xff0c;便于之后的考研復習使用。 首先&#xff0c;對于普通的二階和三階行列式&#xff0c;我們可以直接對其進行拆開&#xff0c;展開。 而對于n階行列式 其行列式的值等于它的任意…

每個架構師都應該讀的八本經典書籍

格雷戈爾霍普在本文討論了8本被視為軟件架構師必讀的經典書籍。 以下是所提及的關鍵書籍的摘要&#xff1a; 1、維特魯威&#xff08;公元前 20 年&#xff09;的《建筑學》&#xff1a; 雖然與軟件架構沒有直接關系&#xff0c;但這部古代文獻被提及&#xff0c;具有歷史背景…

C++特殊類設計單例模式...

文章目錄 請設計一個類&#xff0c;不能被拷貝請設計一個類&#xff0c;只能在堆上創建對象請設計一個類&#xff0c;只能在棧上創建對象請設計一個類&#xff0c;不能被繼承請設計一個類&#xff0c;只能創建一個對象(單例模式)單例模式&#xff1a;餓漢模式&#xff1a;懶漢模…

代發考生戰報:6月25號 南寧 HCIP-Transmission傳輸 H31-341考試884分通過

代發考生戰報&#xff1a;6月25號 南寧 HCIP-Transmission傳輸 H31-341考試884分通過 &#xff0c;今天我和同事兩個人去考的&#xff0c;我考試遇到1個新題&#xff0c;他遇到兩個新題&#xff0c;客服提供的題庫很穩定&#xff0c;全覆蓋了&#xff0c;輕松通過&#xff0c;考…

【語言模型】Xinference的部署過程

一、引言 Xinference&#xff0c;也稱為Xorbits Inference&#xff0c;是一個性能強大且功能全面的分布式推理框架&#xff0c;專為各種模型的推理而設計。無論是研究者、開發者還是數據科學家&#xff0c;都可以通過Xinference輕松部署自己的模型或內置的前沿開源模型。Xinfe…

pikachu靶場 利用Rce上傳一句話木馬案例(工具:中國蟻劍)

目錄 一、準備靶場&#xff0c;進入RCE 二、測試寫入文件 三、使用中國蟻劍 一、準備靶場&#xff0c;進入RCE 我這里用的是pikachu 打開pikachu靶場&#xff0c;選擇 RCE > exec "ping" 測試是否存在 Rce 漏洞 因為我們猜測在這個 ping 功能是直接調用系統…

性能評測系列:云架構擴展演進橫向對比

原始測評報告 性能評測系列&#xff08;PT-010&#xff09;&#xff1a;Spring Boot RDS for MySQL&#xff0c;高并發insert 性能評測系列&#xff08;PT-012&#xff09;&#xff1a;Spring Boot(K8s多實例) RDS for MySQL&#xff0c;高并發insert 性能評測系列&#xff…

一元線性回歸-R語言

# # 安裝包 # install.packages(ggplot2) # library(ggplot2) Sys.setlocale(category LC_ALL, locale English_United States.1252) # Sys.setlocale("LC_ALL","Chinese") x <- c(18, 20, 22, 24, 26, 28, 30) y <- c(26.86, 28.35, 28.87,28.75,…

Linux——vim的配置文件+異常處理

vim的配置文件&#xff1a; [rootserver ~]# vim /etc/vimrc # 輸入以下內容 set nu # 永久設置行號 shell [rootserver ~]# vim /etc/vimrc 或者 vim ~/.vimrc set hlsearch "高亮度反白 set backspace2 "可隨時用退格鍵刪除 set autoindent…

期貨的杠桿怎么計算?

什么是杠桿系數 杠桿系數是指期貨合約價值與保證金之間的比例。它表示投資者只需投入少量資金&#xff0c;就可以控制價值更高的期貨合約。杠桿系數越高&#xff0c;投資者的資金放大倍數就越大&#xff0c;但風險也越大。 什么是期貨保證金呢&#xff1f; 期貨保證金&…

《HelloGitHub》第 99 期

興趣是最好的老師&#xff0c;HelloGitHub 讓你對編程感興趣&#xff01; 簡介 HelloGitHub 分享 GitHub 上有趣、入門級的開源項目。 github.com/521xueweihan/HelloGitHub 這里有實戰項目、入門教程、黑科技、開源書籍、大廠開源項目等&#xff0c;涵蓋多種編程語言 Python、…

Multicolor Dragon-MCD 六彩神龍_RSI

MCDX 六彩神龍 https://www.tradingview.com/script/u2dIgVpN-M2J-Indicator-MCDX/ MCDX is an indicator based on mutilple Relative Strength Index (RSI) with different period, then classify into 3 categories - Retailer, Hot Money and Banker - Green - Retailer零…