Technology sharing

Algorithm Series -- divide and conquer Sorting|re discussing Quick Sorting| Optimization of Quick Sorting| Quick Selection Algorithm

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.

1. Loquamur de celeri sortibus iterum

nucleus velox algorithmus est分治思想Distinguendum et vincendum consilium in tres sequentes gradus dividitur:

  1. Decomposition: Decomponere problema originale in plura similia, minores problemata sub-
  2. Solutio: Si quaestio parva est, directe solvere;
  3. Merge: Solutio problematum originalis aequale est merger solutionum plurium problematum sub- .

Ad vivum algorithmus applicatur:

  1. Decompositio: Quod velox algorithmus quale vult consequi est totam aciem disponere, sed scala magna est, unde oportet invenire viam ad reducere scalam; partes duae, cum elementis a sinistris, quae sunt minora quam velit elementum, omnia dextra sunt majora quam elementa referentia. "Supra processum repetens, totum ordinem absolvere potes. Peracta hac operatione in totum ordinem complent processus supra laeva dextraque intervalla respective.
  2. Celeriter duae subarrayriae recursive usque ad longi- tudinem uniuscuiusque subarray est 0 vel 1, in quo puncto lineae digestae sunt.
  3. Cum subarray per recursationem separatim digessi sunt, nullus gradus additus mergendi requiritur.

2. Codicis exsecutionem et explicationem accuratiorem

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;
    }
    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Retineo responsa:
1.Whystart>=endEstne 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]&gt;=ey?&gt;non potest?

Maior quam vel aequalis maxime est processus重复元素问题
Exempli gratia, ordo est[6,6,6,6,6]Si sit &gt;, monstrator dexter non movebit, nec sinister movebit neutrum, et hærebit in ansa infinita.

4. Cur fovea fodiendi modum dicitur?

Cum r regula incurrit primumarr[r] = arr[l]hoc tempore, l situs blank, foveam formans.


3. Optimization velox generis

Duae partes optimae principales sunt:

  1. Delectu probatio valoris versorium probari potest quod, cum valor probatio passim selecta est, tempus multiplicitas celeris modi appropinquat.O(N*logN)id est, optime complexionem
  2. Processus elementorum iteratorum: Si intra intervallum elementa frequentia repetuntur, illa versio celeris algorithmus eadem elementa multiplex repetet tempora;数组分三块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

Insert imaginem descriptionis hic
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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • Noticel,r的起始位置, elementum primum et ultimum未处理状态, ita `l, r non potest haec duo elementa monstrare et extra intervallum esse
  • Sic dicta ordinata dividitur in tres partes, quod est usura三个指针去分别维护四个区间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
Insert imaginem descriptionis hic
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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

Insert imaginem descriptionis hic
2. Passim eligere basis valorem
Passim eligere base valorem per temere numeris

        int pivot = nums[start + new Random().nextInt(end - start + 1)];
        //               起始位置      随机产生的偏移量

  • 1
  • 2
  • 3

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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

Insert imaginem descriptionis hic

  • Efficientiam significantly melius

4. Velox lectio algorithmus

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

  • Vim violentam solutio est directe utendisortSort et tunc revertetur ad Kth maxima
  • temporis complexionem;O(N*logN)
  • Spatium complexionis:O(logN)Rare vocat generatae recursionis

Deinceps 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;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • The idea of ​​the quick selection algorithm is very similar to that of quick sort. tempus multiplicitas celeris lectio algorithmus reduciturO(N)