2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Praefatio: Hic articulus accurata responsionibus quibusdam dubiis de algorithm veterum discendorum celeris sortis praebet, et versionem optimized algorithmum celeris sortis fundamentalis praebet.
nucleus velox algorithmus est分治思想
Distinguendum et vincendum consilium in tres sequentes gradus dividitur:
Ad vivum algorithmus applicatur:
Clavis code for velox generis est如何根据基准元素划分数组区间(parttion)
sunt multae compositionis modi, una tantum ratio.挖坑法
Codicis:
class Solution {
public int[] sortArray(int[] nums) {
quick(nums, 0, nums.length - 1);
return nums;
}
private void quick(int[] arr, int start, int end) {
if(start >= end) return;// 递归结束条件
int pivot = parttion(arr, start, end);
// 递归解决子问题
quick(arr, start, pivot - 1);
quick(arr, pivot + 1, end);
}
// 挖坑法进行分解
private int parttion(int[] arr, int left, int right) {
int key = arr[left];
while(left < right) {
while(left < right && arr[right] >= key) right--;
arr[left] = arr[right];
while(left < right && arr[left] <= key) ++left;
arr[right] = arr[left];
}
arr[left] = key;
return left;
}
}
Retineo responsa:
1.Whystart>=end
Estne finis recursionis conditio?
Postremam magnitudinem quaestionis sub- problema est 1 , id est, unum tantum elementum tempus.
2. Cur dextra primum ibit?
Hoc positum est qui primus vadit
基准元素的位置
,In superiore codice, elementum basis (clavis) est elementum sinistrumleft
, elementum basi majus quam basi primum incurrit, et deinde exsequiturarr[right] = arr[left]
, Non ex salutarisarr[right]
, elementum peribit
Si ad primum dextrum pergis, primum rectum elementum minoris basi elementi incurrit, deinde efficitarr[left]=arr[right]
quod sinistrum hoc tempore non movetur, adhuc cardo est, sed cardo clavem a nobis servata est.
3.Cur arr[ius]>=ey?>non potest?
Maior quam vel aequalis maxime est processus
重复元素问题
Exempli gratia, ordo est[6,6,6,6,6]
Si sit >, monstrator dexter non movebit, nec sinister movebit neutrum, et hærebit in ansa infinita.
4. Cur fovea fodiendi modum dicitur?
Cum r regula incurrit primum
arr[r] = arr[l]
hoc tempore, l situs blank, foveam formans.
Duae partes optimae principales sunt:
O(N*logN)
id est, optime complexionem数组分三块
Eodem tempore, si casus speciales testium invenimus (sequential ordinatus vel e diverso ordinatus), tempus multiplicitatem in se deducit.O(N^2)
Primo, secundum quaestionem;digerere color) Intelligo quid数组分三块
resolvere
Codicis:
class Solution {
public void sortColors(int[] nums) {
// 分治 --
// 1.定义三指针
int i = 0;// 遍历整个数组
int l = -1, r = nums.length;
while(i < r) {
if(nums[i] == 0) swap(nums,++l,i++);
else if(nums[i] == 1) i++;
else swap(nums,--r,i);
}
return;
}
private void swap(int[] nums,int x,int y) {
int tmp = nums[x]; nums[x] = nums[y]; nums[y] = tmp;
}
}
l,r的起始位置
, elementum primum et ultimum未处理状态
, ita `l, r non potest haec duo elementa monstrare et extra intervallum esse三个指针去分别维护四个区间
unum intervallum est未处理区间
ut cursim moveat, omnia intervalla discurrunt, postremo tria tantum intervalla sunt.Applicare supra notiones ad快速排序的parttion中
ultimus effectus in tria tempora dividitur
Codicis:
class Solution {
// 快速排序优化版
// 分解--解决--合并
public int[] sortArray(int[] nums) {
qsort(nums, 0, nums.length - 1);
return nums;
}
private void qsort(int[] nums, int start, int end) {
if(start >= end) return;// 递归结束条件
// 分解
int pivot = nums[start];
int l = start - 1, r = end + 1, i = start;
while(i < r) {
int cur = nums[i];
if(cur < pivot) swap(nums, ++l, i++);
else if(cur == pivot) ++i;
else swap(nums, --r, i);
}
// [start, l] [l+1, r-1] [r, end]
// 递归解决
qsort(nums, start, l);
qsort(nums, r, end);
}
private void swap(int[] nums,int i, int j) {
int tmp = nums[i]; nums[i] = nums[j]; nums[j] = tmp;
}
}
2. Passim eligere basis valorem
Passim eligere base valorem per temere numeris
int pivot = nums[start + new Random().nextInt(end - start + 1)];
// 起始位置 随机产生的偏移量
Integram meliorem codicem:
class Solution {
// 快速排序优化版
// 分解--解决--合并
public int[] sortArray(int[] nums) {
qsort(nums, 0, nums.length - 1);
return nums;
}
private void qsort(int[] nums, int start, int end) {
if(start >= end) return;// 递归结束条件
// 分解
int pivot = nums[start + new Random().nextInt(end - start + 1)];
int l = start - 1, r = end + 1, i = start;
while(i < r) {
int cur = nums[i];
if(cur < pivot) swap(nums, ++l, i++);
else if(cur == pivot) ++i;
else swap(nums, --r, i);
}
// [start, l] [l+1, r-1] [r, end]
// 递归解决
qsort(nums, start, l);
qsort(nums, r, end);
}
private void swap(int[] nums,int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
}
Celer lectio algorithmus est基于快速排序优化版本
Tempus complexionemO(N)
Delectu algorithmus, usus missionis第K大/前K大
sicut arbitrium exitibus
01.The Kth elementum maximum in acie
Link: https://leetcode.cn/problems/kth-largest-element-in-an-array/
resolvere
sort
Sort et tunc revertetur ad Kth maximaO(N*logN)
O(logN)
Rare vocat generatae recursionisDeinceps lectio algorithmus velox ad efficiendum adhibeturO(N)
Tempus complexionem
Codicis:
class Solution {
public int findKthLargest(int[] nums, int k) {
return qsort(nums, 0, nums.length - 1, k);
}
private int qsort(int[] nums, int start, int end, int k) {
if(start >= end) return nums[start];
int pivot = nums[start + new Random().nextInt(end - start + 1)];
// 数组分三块 <pivot ==pivot >pivot
int l = start - 1, r = end + 1, i = start;
while(i < r) {
if(nums[i] < pivot) swap(nums, ++l, i++);
else if(nums[i] == pivot) ++i;
else swap(nums, --r, i);
}
// [start, l] [l+1, r - 1] [r, end]
int c = end - r + 1, b = r - 1 - (l + 1) + 1, a = l - start + 1;
// 分情况讨论 进行选择
if(c >= k) return qsort(nums, r, end, k);
else if(b + c >= k) return pivot;
else return qsort(nums, start, l, k - b - c);// 找较小区间的第(k-b-c)大
}
private void swap(int[] arr, int i, int j) {
int tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
}
O(N)