当前位置:   article > 正文

C++力扣Leetcode算法4--排序算法

C++力扣Leetcode算法4--排序算法

目录

快速排序--递归

归并排序--递归

插入排序

冒泡排序

选择排序

215 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

347. 前 K 个高频元素


快速排序--递归

  1. void quick_sort(vector<int> &nums, int l, int r) {
  2. if (l + 1 >= r) {
  3. return;
  4. }
  5. int first = l, last = r - 1, key = nums[first];
  6. while (first < last){
  7. while(first < last && nums[last] >= key) {
  8. --last;
  9. }
  10. nums[first] = nums[last];
  11. while (first < last && nums[first] <= key) {
  12. ++first;
  13. }
  14. nums[last] = nums[first];
  15. }
  16. nums[first] = key;
  17. quick_sort(nums, l, first);
  18. quick_sort(nums, first + 1, r);
  19. }

归并排序--递归

  1. void merge_sort(vector<int> &nums, int l, int r, vector<int> &temp) {
  2. if (l + 1 >= r) {
  3. return;
  4. }
  5. // divide
  6. int m = l + (r - l) / 2;
  7. merge_sort(nums, l, m, temp);
  8. merge_sort(nums, m, r, temp);
  9. // conquer
  10. int p = l, q = m, i = l;
  11. while (p < m || q < r) {
  12. if (q >= r || (p < m && nums[p] <= nums[q])) {
  13. temp[i++] = nums[p++];
  14. } else {
  15. temp[i++] = nums[q++];
  16. }
  17. }
  18. for (i = l; i < r; ++i) {
  19. nums[i] = temp[i];
  20. }
  21. }

插入排序

  1. void insertion_sort(vector<int> &nums, int n) {
  2. for (int i = 0; i < n; ++i) {
  3. for (int j = i; j > 0 && nums[j] < nums[j-1]; --j) {
  4. swap(nums[j], nums[j-1]);
  5. }
  6. }
  7. }

冒泡排序

  1. void bubble_sort(vector<int> &nums, int n) {
  2. bool swapped;
  3. for (int i = 1; i < n; ++i) {
  4. swapped = false;
  5. for (int j = 1; j < n - i + 1; ++j) {
  6. if (nums[j] < nums[j-1]) {
  7. swap(nums[j], nums[j-1]);
  8. swapped = true;
  9. }
  10. }
  11. if (!swapped) {
  12. break;
  13. }
  14. }
  15. }

选择排序

  1. void selection_sort(vector<int> &nums, int n) {
  2. int mid;
  3. for (int i = 0; i < n - 1; ++i) {
  4. mid = i;
  5. for (int j = i + 1; j < n; ++j) {
  6. if (nums[j] < nums[mid]) {
  7. mid = j;
  8. }
  9. }
  10. swap(nums[mid], nums[i]);
  11. }
  12. }

排序调用方法

  1. void sort() {
  2. vector<int> nums = {1,3,5,7,2,6,4,8,9,2,8,7,6,0,3,5,9,4,1,0};
  3. vector<int> temp(nums.size());
  4. sort(nums.begin(), nums.end());
  5. quick_sort(nums, 0, nums.size());
  6. merge_sort(nums, 0, nums.size(), temp);
  7. insertion_sort(nums, nums.size());
  8. bubble_sort(nums, nums.size());
  9. selection_sort(nums, nums.size());
  10. }

215 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

书中最优解

  1. int pointers::findKthLargest(vector<int>& nums, int k)
  2. {
  3. int l = 0, r = nums.size() - 1, target = nums.size() - k;
  4. while (l < r) {
  5. int mid = quickSelection(nums, l, r);
  6. if (mid == target) {
  7. return nums[mid];
  8. }
  9. if (mid < target) {
  10. l = mid + 1;
  11. }
  12. else {
  13. r = mid - 1;
  14. }
  15. }
  16. return nums[l];
  17. }
  18. // 辅函数 - 快速选择
  19. int quickSelection(vector<int>& nums, int l, int r) {
  20. int i = l + 1, j = r;
  21. while (true) {
  22. while (i < r && nums[i] <= nums[l]) {
  23. ++i;
  24. }
  25. while (l < j && nums[j] >= nums[l]) {
  26. --j;
  27. }
  28. if (i >= j) {
  29. break;
  30. }
  31. swap(nums[i], nums[j]);
  32. }
  33. swap(nums[l], nums[j]);
  34. return j;
  35. }

本人写,提交超出时间限制

  1. int pointers::findKthLargest(vector<int>& nums, int k)
  2. {
  3. int len = nums.size();
  4. for (int i = 0; i < len; ++i) {
  5. for (int j = i; j >0 && nums[j]<nums[j-1]; --j) {
  6. swap(nums[j], nums[j - 1]);
  7. }
  8. }
  9. return nums[len-k];
  10. }

347. 前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。
你可以按 任意顺序 返回答案。

解:桶排序

书中最优解

  1. vector<int> pointers::topKFrequent(vector<int>& nums, int k)
  2. {
  3. unordered_map<int, int> counts;
  4. /*unordered_map容器用来存储键值对,其中键为int型,值为int型,
  5. 可以用counts[key]++方式增加某个键的值,如果键不存在,会自动插一个新的键值对,值为0
  6. 由于unordered_map不允许存储具有重复键的元素,因此count()函数本质上检查unordered_map中是否存在具有给定键的元素。
  7. */
  8. int max_count = 0;
  9. //统计每个元素出现的次数,实现数:频率
  10. for (const int& num : nums) {
  11. max_count = max(max_count, ++counts[num]);
  12. }
  13. vector<vector<int>> buckets(max_count + 1); //行数max_count + 1
  14. //将次数为i的元素放入i桶中,实现频率:数,通过键值相互交换达到value排序的目的,这种写法更符合C++
  15. for (const auto& p : counts) {
  16. buckets[p.second].push_back(p.first);
  17. }
  18. vector<int> ans;
  19. for (int i = max_count; i >= 0 && ans.size() < k; --i) {
  20. for (const int& num : buckets[i]) {
  21. ans.push_back(num);
  22. if (ans.size() == k) {
  23. break;
  24. }
  25. }
  26. }
  27. return ans;
  28. }

学习:leetcode-347. 前K个高频元素 - ggaoda - 博客园 (cnblogs.com)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/415597
推荐阅读
相关标签
  

闽ICP备14008679号