当前位置:网站首页>Leetcode (215) -- the kth largest element in the array
Leetcode (215) -- the kth largest element in the array
2022-07-04 07:35:00 【SmileGuy17】
Leetcode(215)—— The... In the array K The biggest element
subject
Given an array of integers nums And integer k, Please return the... In the array k The biggest element .
Please note that , What you need to look for is the number after array sorting k The biggest element , Not the first. k A different element .
Example 1:
Input : [3,2,1,5,6,4] and k = 2
Output : 5
Example 2: Input : [3,2,3,1,2,4,5,5,6] and k = 4
Output : 4
Tips :
- 1 1 1 <= k <= nums.length <= 1 0 4 10^4 104
- − 1 0 4 -10^4 −104 <= nums[i] <= 1 0 4 10^4 104
Answer key
Method 1 : Bubble sort
Ideas
The principle of bubble sorting
Code implementation
my :
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
if(n == 1) return nums[0];
bool swapped;
for(int i = 0; i < n; i++){
swapped = false;
for(int t = 0; t < n-i-1; t++){
if(nums[t] < nums[t+1]){
swap(nums[t], nums[t+1]);
swapped = true;
}
}
if(!swapped) break;
}
return nums[k-1];
}
};
Complexity analysis
Time complexity : O ( n log n ) O(n \log n) O(nlogn)
Spatial complexity : O ( 1 ) O(1) O(1)
Method 2 : Simple selection sort
Ideas
The principle of simple selection sorting
Code implementation
my :
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
if(n == 1) return nums[0];
int max, tmp;
for(int i = 0; i < n; i++){
max = i;
for(int t = i+1; t < n; t++){
if(nums[max] < nums[t]) max = t;
}
tmp = nums[i];
nums[i] = nums[max];
nums[max] = tmp;
}
return nums[k-1];
}
};
Complexity analysis
Time complexity : O ( n log n ) O(n \log n) O(nlogn)
Spatial complexity : O ( 1 ) O(1) O(1)
Method 3 : Direct insert sort
Ideas
The principle of direct insertion sort
Code implementation
my :
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
if(n == 1) return nums[0];
for(int i = 1; i < n; i++){
// Set the length of the first element as 1 Sequence , So start sorting from the second element
for(int t = i; t > 0 && nums[t] > nums[t-1]; t--)
swap(nums[t], nums[t-1]);
}
return nums[k-1];
}
};
Complexity analysis
Time complexity : O ( n log n ) O(n \log n) O(nlogn)
Spatial complexity : O ( 1 ) O(1) O(1)
Method four : Shell Sort
Ideas
The principle of hill ordering
Code implementation
my :
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
int n = nums.size();
if(n == 1) return nums[0];
int increment = n/3+1; // The minimum guarantee is 1
while(increment > 0){
// Direct insert sort
for(int i = 0; i < n; i++){
for(int t = i; t-increment >= 0 && nums[t] > nums[t-increment]; t -= increment)
swap(nums[t], nums[t-increment]);
}
increment--;
}
return nums[k-1];
}
};
Complexity analysis
Time complexity : O ( n 3 / 2 ) O(n^{3/2}) O(n3/2)
Spatial complexity : O ( 1 ) O(1) O(1)
Method five : Merge sort
Ideas
The principle of merging and sorting
Code implementation
my ( recursive ):
class Solution {
void MSort(vector<int>& nums, int l, int r){
if(l == r)
nums[l] = nums[l];
else{
vector<int> Tmp(r-l+1);
int mid = (l+r)/2;
MSort(nums, l, mid);
MSort(nums, mid+1, r);
// Merge the above two groups
int p1 = l, p2 = mid+1, p = 0;
while(p1 <= mid && p2 <= r){
if(nums[p1] < nums[p2])
Tmp[p++] = nums[p2++];
else Tmp[p++] = nums[p1++];
}
if(p1 <= mid)
while(p1 <= mid) Tmp[p++] = nums[p1++];
if(p2 <= r)
while(p2 <= r) Tmp[p++] = nums[p2++];
p = 0;
while(l <= r)
nums[l++] = Tmp[p++];
}
}
public:
int findKthLargest(vector<int>& nums, int k) {
if(nums.size() == 1) return nums[0];
// for(int i = 0; i < n; i++){}
// Merge sort
MSort(nums, 0, nums.size()-1);
return nums[k-1];
}
};
Complexity analysis
Time complexity : O ( n log n ) O(n \log n) O(nlogn)
Spatial complexity : O ( n ) O(n) O(n)
Methods six : Quick sort ( improvement ——「 Choose... Quickly 」 Algorithm )
Ideas
There must be operations to disrupt the array , That is, the pivot selection is not fixed , Otherwise, it is easy to encounter extreme situations, resulting in a time complexity of O ( n 2 ) O(n^2) O(n2).
We can use quick sorting to solve this problem , First sort the original array , And back to the penultimate k k k A place , The average time complexity is O ( n log n ) O(n \log n) O(nlogn), But in fact, we can do it faster .
First, let's review the quick sort , This is a typical divide and conquer algorithm . Let's look at arrays a [ l ⋯ r ] a[l \cdots r] a[l⋯r] The process of quick sorting is ( Reference resources 《 Introduction to algorithms 》):
- decompose : Will array a [ l ⋯ r ] a[l \cdots r] a[l⋯r] 「 Divide 」 Into two subarrays a [ l ⋯ q − 1 ] a[l \cdots q - 1] a[l⋯q−1]]、 a [ q + 1 ⋯ r ] a[q + 1 \cdots r] a[q+1⋯r], bring a [ l ⋯ q − 1 ] a[l \cdots q - 1] a[l⋯q−1] Each element in is less than or equal to a [ q ] a[q] a[q], And a [ q ] a[q] a[q] Less than or equal to a [ q + 1 ⋯ r ] a[q + 1 \cdots r] a[q+1⋯r] Every element in . among , Calculate subscript q q q It's also 「 Divide 」 Part of the process .
- solve : Fast sort through recursive calls , Pair arrays a [ l ⋯ q − 1 ] a[l \cdots q - 1] a[l⋯q−1] and a [ q + 1 ⋯ r ] a[q + 1 \cdots r] a[q+1⋯r] Sort .
- Merge : Because subarrays are sorted in place , So there is no need to merge , a [ l ⋯ r ] a[l \cdots r] a[l⋯r] It's in order .
- As mentioned above 「 Divide 」 The process is : From subarray a [ l ⋯ r ] a[l \cdots r] a[l⋯r] Select any element in x x x As principal element , Adjust the elements of the subarray so that the elements on the left are less than or equal to it , The elements on the right are greater than or equal to it , x x x The final position of the is q q q.
From this we can find that every time we pass 「 Divide 」 After the operation , We must be able to determine the final position of an element , namely x x x The final position of the is q q q, And guarantee a [ l ⋯ q − 1 ] a[l \cdots q - 1] a[l⋯q−1] Each element in is less than or equal to a [ q ] a[q] a[q], And a [ q ] a[q] a[q] Less than or equal to a [ q + 1 ⋯ r ] a[q + 1 \cdots r] a[q+1⋯r] Every element in . therefore As long as a certain division q q q It's the penultimate k k k When subscript , We have found the answer . We only care about this , as for a [ l ⋯ q − 1 ] a[l \cdots q - 1] a[l⋯q−1] and a [ q + 1 ⋯ r ] a[q+1 \cdots r] a[q+1⋯r] Whether it's orderly , We don't care .
therefore , We can Improve the quick sort algorithm To solve this problem :
In the process of decomposition , We'll divide the subarray , If you divide it up q q q Just the subscript we need ( That is, when you encounter k == q-1, here a [ q ] a[q] a[q] Sinister k − 1 k-1 k−1 Each element is greater than or equal to it , The elements on the right are less than or equal to it ), Go straight back a [ q ] a[q] a[q]; otherwise , If q q q Smaller than the target subscript , Just recurse the right subinterval , Otherwise, recursive left subinterval .
In this way, we can change the original recursive two intervals into only recursive one interval , Improved time efficiency . This is it. 「 Choose... Quickly 」 Algorithm .
We know the performance of quicksort and 「 Divide 」 The length of the subarray is closely related to . Intuitively understand if each time the scale is n n n We are all divided into 1 1 1 and n − 1 n - 1 n−1, Every time I recurse, I send it to n − 1 n - 1 n−1 Recursion in the collection of , This situation is the worst , The price of time is O ( n 2 ) O(n ^ 2) O(n2). We can introduce randomization to accelerate this process , The expectation of its time cost is O ( n ) O(n) O(n), The proof process can refer to 「《 Introduction to algorithms 》9.2: The selection algorithm expected to be linear 」.
Code implementation
Leetcode Official explanation :
class Solution {
public:
int quickSelect(vector<int>& a, int l, int r, int index) {
int q = randomPartition(a, l, r);
if (q == index) {
return a[q];
} else {
return q < index ? quickSelect(a, q + 1, r, index) : quickSelect(a, l, q - 1, index);
}
}
inline int randomPartition(vector<int>& a, int l, int r) {
int i = rand() % (r - l + 1) + l;
swap(a[i], a[r]);
return partition(a, l, r);
}
inline int partition(vector<int>& a, int l, int r) {
int x = a[r], i = l - 1;
for (int j = l; j < r; ++j) {
if (a[j] <= x) {
swap(a[++i], a[j]);
}
}
swap(a[i + 1], a[r]);
return i + 1;
}
int findKthLargest(vector<int>& nums, int k) {
srand(time(0));
return quickSelect(nums, 0, nums.size() - 1, nums.size() - k);
}
};
my ( recursive ):
class Solution {
int Partition(vector<int>& nums, int l, int r){
// Scramble the array , Take the middle of three numbers
int mid = l+(r-l)/2;
if(nums[l] > nums[r]) swap(nums[l], nums[r]);
if(nums[mid] > nums[r]) swap(nums[mid], nums[r]);
if(nums[mid] > nums[l]) swap(nums[mid], nums[l]);
// here nums[l] Is the median of three numbers
int privot = nums[l]; // Select the first as the pivot
while(l < r){
while(l < r && nums[r] <= privot)
r--;
nums[l] = nums[r];
while(l < r && nums[l] >= privot)
l++;
nums[r] = nums[l];
}
nums[l] = privot;
return l;
}
void Quicksort(vector<int>& nums, int l, int r){
if(l < r){
int privot = Partition(nums, l, r); // Get pivot
Quicksort(nums, l, privot-1);
Quicksort(nums, privot+1, r);
}
}
public:
int findKthLargest(vector<int>& nums, int k) {
if(nums.size() == 1) return nums[0];
// Quick sort
Quicksort(nums, 0, nums.size()-1);
return nums[k-1];
}
};
Complexity analysis
Time complexity :Leetcode The time complexity of the official solution is O ( n ) O(n) O(n). The average time complexity of conventional quick sort is O ( n log n ) O(n \log n) O(nlogn).
Spatial complexity : O ( log n ) O(\log n) O(logn), The expected space cost of recursively using stack space is O ( log n ) O(\log n) O(logn).
Methods seven : Heap sort
Ideas
Build a big top pile , Then delete k − 1 k-1 k−1 A heap top element , Then the heap top element at this time is k k k Big elements .
Code implementation
Leetcode Official explanation :
class Solution {
public:
void maxHeapify(vector<int>& a, int i, int heapSize) {
int l = i * 2 + 1, r = i * 2 + 2, largest = i;
if (l < heapSize && a[l] > a[largest]) {
largest = l;
}
if (r < heapSize && a[r] > a[largest]) {
largest = r;
}
if (largest != i) {
swap(a[i], a[largest]);
maxHeapify(a, largest, heapSize);
}
}
void buildMaxHeap(vector<int>& a, int heapSize) {
for (int i = heapSize / 2; i >= 0; --i) {
maxHeapify(a, i, heapSize);
}
}
int findKthLargest(vector<int>& nums, int k) {
int heapSize = nums.size();
buildMaxHeap(nums, heapSize);
for (int i = nums.size() - 1; i >= nums.size() - k + 1; --i) {
swap(nums[0], nums[i]);
--heapSize;
maxHeapify(nums, 0, heapSize);
}
return nums[0];
}
};
Complexity analysis
Time complexity : O ( n log n ) O(n \log n) O(nlogn), The time cost of building the reactor is O ( n ) O(n) O(n), The total cost of deletion is O ( k log n ) O(k \log n) O(klogn), because k < n k < n k<n, Therefore, the asymptotic time is complex O ( n + k log n ) O(n + k \log n) O(n+klogn) Simplify O ( n log n ) O(n \log n) O(nlogn).
Spatial complexity : O ( log n ) O(\log n) O(logn), That is, the space cost of recursive writing using stack space .
边栏推荐
- 果果带你写链表,小学生看了都说好
- What are the work contents of operation and maintenance engineers? Can you list it in detail?
- 时序数据库 InfluxDB 2.2 初探
- Four sets of APIs for queues
- Node connection MySQL access denied for user 'root' @ 'localhost' (using password: yes
- When JDBC connects to es query, is there a God who meets the following situation?
- The frost peel off the purple dragon scale, and the xiariba people will talk about database SQL optimization and the principle of indexing (primary / secondary / clustered / non clustered)
- Node foundation ~ node operation
- Rapidjson reading and writing JSON files
- Zephyr Learning note 2, Scheduling
猜你喜欢

flask-sqlalchemy 循环引用

L2-013 red alarm (C language) and relevant knowledge of parallel search

Guoguo took you to write a linked list, and the primary school students said it was good after reading it

【森城市】GIS数据漫谈(一)

Practice (9-12 Lectures)

如何用MOS管来实现电源防反接电路

Preliminary study on temporal database incluxdb 2.2

socket inet_ pton() inet_ Ntop() function (a new network address translation function, which converts the expression format and numerical format to each other. The old ones are inet_aton(), INET_ ntoa

How to send mail with Jianmu Ci

Xcode 14之大变化详细介绍
随机推荐
Comparison between applet framework and platform compilation
jdbc连接es查询的时候,有遇到下面这种情况的大神嘛?
Introduction to sap commerce cloud B2B organization function
Data double write consistency between redis and MySQL
L1-025 positive integer a+b (15 points)
Life planning (flag)
BUUCTF(4)
电脑通过Putty远程连接树莓派
Zephyr study notes 2, scheduling
Used on windows Bat file startup project
L1-023 output gplt (20 points)
MySQL中的文本处理函数整理,收藏速查
Types of references in BibTex
Two years ago, the United States was reluctant to sell chips, but now there are mountains of chips begging China for help
[kubernetes series] kubesphere is installed on kubernetes
Tri des fonctions de traitement de texte dans MySQL, recherche rapide préférée
I was pressed for the draft, so let's talk about how long links can be as efficient as short links in the development of mobile terminals
Unity opens the explorer from the inspector interface, selects and records the file path
Text processing function sorting in mysql, quick search of collection
Book list | as the technical support Party of the Winter Olympics, Alibaba cloud's technology is written in these books!