问题描述:输入一个数组求出数组中指定的第k大元并输出。
样例
Example 1:
Input: n = 1, nums = [1,3,4,2] Output: 4
Example 2:
Input: n = 3, nums = [9,3,2,4,8] Output: 4
思路一:直接使用反向迭代器即可。
1 class Solution { 2 public: 3 int kthLargestElement(int n, vector<int> &nums) { 4 // write your code here 5 sort(nums.rbegin(), nums.rend()); 6 return nums[n-1]; 7 } 8 };
思路二:最直接的思路便是排序,然后通过数组下标直接输出第k大元。
首先使用简单的冒泡排序bubble(时间复杂度较大O(n²);
扫描二维码关注公众号,回复:
5847095 查看本文章
1 /*bubble排序1*/ 2 int bubble1(int k, int[] nums){ 3 int size = nums.length; 4 for(int i = 0; i < k ; i++){ 5 int max = nums[i], index = i; 6 for(int j = i + 1; j < size; j++){ 7 if(nums[j] > max){ 8 max = nums[j]; 9 index = j; 10 } 11 } 12 nums[index] = nums[i]; 13 nums[i] = max; 14 } 15 return nums[k-1]; 16 }
1 /*bubble排序2*/ 2 int bubble2(int k, int[] nums){ 3 int flag = 1; 4 int size = nums.length; 5 for(int i = 1; i < size & flag == 1; i++){ 6 flag = 0; 7 for(int j = 0; j < size-1; j++) 8 if(nums[j] < nums[j+1]){ 9 int temp = nums[j+1]; 10 nums[j+1] = nums[j]; 11 nums[j] = temp; 12 flag = 1; 13 } 14 } 15 return nums[k-1]; 16 }
思路三:快速排序时间复杂度为(O(nlogn),最坏情况下会退化到O(n²)
核心部分为partition
1 class Solution { 2 public: 3 int kthLargestElement(int n, vector<int> &nums) { 4 // write your code here 5 QuickSort(nums, 0, nums.size()-1); 6 return nums[n-1]; 7 } 8 9 int partition(vector<int> &nums, int l, int r){ 10 int v = nums[l]; 11 int j = l; 12 for(int i = l+1; i <= r; i++){ 13 if(nums[i] > v){ 14 swap(nums[i], nums[j+1]); 15 j++; 16 } 17 } 18 swap(nums[l], nums[j]); 19 return j; 20 } 21 22 void QuickSort(vector<int> &nums, int l, int r){ 23 if(l <= r) 24 return; 25 int p = partition(nums, l, r); 26 QuickSort(nums, l, p-1); //对数组前半部分排序 27 QuickSort(nums, p+1, r); //对数组后半部分排序 28 }
29 };
下面在快速排序的基础上改进,运用快速排序框架,不过快排中的基准匀速采用随机划分那样指定为一个固定的值,此方法时间复杂度为O(n)
1 class Solution { 2 public: 3 int kthLargestElement(int n, vector<int> &nums) { 4 // write your code here 5 srand(time(NULL)); 6 return QuickSort(nums, 0, nums.size()-1, n); 7 } 8 9 int partition(vector<int> &nums, int l, int r){ 10 swap(nums[l], nums[rand() % (r-l+1)+l]); 11 int v = nums[l]; 12 int j = l; 13 for(int i = l+1; i <= r; i++){ 14 if(nums[i] > v){ 15 swap(nums[i], nums[j+1]); 16 j++; 17 } 18 } 19 swap(nums[l], nums[j]); 20 return j; 21 } 22
//该算法使用了快速排序的框架,不同的是,快速排序通过递归框架
//对数组进行排序,但此算法通过递归框架只对数组中的第k元进行筛选,
//递归的出口不同,快排递归出口为high>low,但该算法递归出口为n-1==p-1 23 int QuickSort(vector<int> &nums, int l, int r, int n){ 24 if(l == r) 25 return nums[l]; 26 int p = partition(nums, l, r); //对数组nums进行划分 27 int j = p - l; //数组从l开始,所以数组下标从p-1开始 28 if(n-1 == j) 29 return nums[p]; //递归出口,返回该元素 30 else if(n-1 < j) 31 return QuickSort(nums, l, p-1, n); 32 else 33 return QuickSort(nums, p+1, r, n-j-1); 34 } 35 };