归并排序
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| void merge(vector<int> &arr, int left, int mid, int right, vector<int> &temp) { |
| |
| int i = left; |
| int j = mid + 1; |
| int index = 0; |
| while (i <= mid && j <= right) { |
| if (arr[i] < arr[j]) |
| temp[index++] = arr[i++]; |
| else |
| temp[index++] = arr[j++]; |
| } |
| |
| while (i <= mid) temp[index++] = arr[i++]; |
| while (j <= right) temp[index++] = arr[j++]; |
| |
| index = 0; |
| while (left <= right) arr[left++] = temp[index++]; |
| } |
| |
| |
| |
| |
| |
| void divide(vector<int> &arr, int left, int right, vector<int> &temp) { |
| if (left >= right) return; |
| int mid = left + ((right - left) >> 2); |
| |
| divide(arr, left, mid, temp); |
| |
| divide(arr, mid + 1, right, temp); |
| |
| merge(arr, left, mid, right, temp); |
| } |
| |
| |
| void mergeSort(vector<int> &arr) { |
| vector<int> temp(arr.size()); |
| divide(arr, 0, arr.size() - 1, temp); |
| } |
| |
| vector<int> sortArray(vector<int> &nums) { |
| mergeSort(nums); |
| return nums; |
| } |
| }; |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| |
| void merge(vector<int> &arr, int left, int mid, int right, vector<int> &temp) { |
| |
| int i = left; |
| int j = mid + 1; |
| int index = 0; |
| while (i <= mid && j <= right) { |
| if (arr[i] < arr[j]) |
| temp[index++] = arr[i++]; |
| else |
| temp[index++] = arr[j++]; |
| } |
| |
| while (i <= mid) temp[index++] = arr[i++]; |
| while (j <= right) temp[index++] = arr[j++]; |
| |
| index = 0; |
| while (left <= right) arr[left++] = temp[index++]; |
| } |
| |
| |
| |
| void mergeSort(vector<int> &arr) { |
| vector<int> temp(arr.size()); |
| int n = arr.size(); |
| |
| for (int left, mid, right, step = 1; step < n; step <<= 1) { |
| left = 0; |
| |
| while (left < n) { |
| mid = left + step - 1; |
| |
| if (mid + 1 >= n) break; |
| |
| right = min(left + (step << 1) - 1, n - 1); |
| merge(arr, left, mid, right, temp); |
| |
| left = right + 1; |
| } |
| } |
| } |
| |
| vector<int> sortArray(vector<int> &nums) { |
| mergeSort(nums); |
| return nums; |
| } |
| }; |
归并分治
- 思考一个问题在大范围上的答案,是否等于:左部分答案 + 右部分答案 + 跨越左右产生的答案
- 计算跨越左右产生的答案时,如果加上左右两侧都有序,能不能简化计算
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| vector<int> temp; |
| |
| void merge(vector<int> &arr, int left, int mid, int right) { |
| int i = left; |
| int j = mid + 1; |
| int index = 0; |
| while (i <= mid && j <= right) { |
| if (arr[i] <= arr[j]) { |
| temp[index++] = arr[i++]; |
| } else { |
| temp[index++] = arr[j++]; |
| } |
| } |
| while (i <= mid) temp[index++] = arr[i++]; |
| while (j <= right) temp[index++] = arr[j++]; |
| index = 0; |
| while (left <= right) arr[left++] = temp[index++]; |
| } |
| |
| |
| long divide(vector<int> &arr, int left, int right) { |
| if (left >= right) return 0; |
| int mid = left + ((right - left) >> 1); |
| |
| long leftSum = divide(arr, left, mid); |
| long rightSum = divide(arr, mid + 1, right); |
| |
| long midSum = 0; |
| for (int l = left, r = mid + 1, sum = 0; r <= right; r++) { |
| |
| while (l <= mid && arr[l] <= arr[r]) { |
| sum += arr[l++]; |
| } |
| midSum += sum; |
| } |
| |
| merge(arr, left, mid, right); |
| return leftSum + midSum + rightSum; |
| } |
| |
| int main() { |
| int n; |
| cin >> n; |
| vector<int> arr(n); |
| temp.resize(n); |
| for (int i = 0; i < n; ++i) |
| cin >> arr[i]; |
| cout << divide(arr, 0, n - 1); |
| } |
| #include <iostream> |
| #include <vector> |
| |
| using namespace std; |
| |
| class Solution { |
| public: |
| vector<int> temp; |
| |
| void merge(vector<int> &arr, int left, int mid, int right) { |
| int i = left; |
| int j = mid + 1; |
| int index = 0; |
| while (i <= mid && j <= right) { |
| if (arr[i] <= arr[j]) { |
| temp[index++] = arr[i++]; |
| } else { |
| temp[index++] = arr[j++]; |
| } |
| } |
| while (i <= mid) temp[index++] = arr[i++]; |
| while (j <= right) temp[index++] = arr[j++]; |
| index = 0; |
| while (left <= right) arr[left++] = temp[index++]; |
| } |
| |
| int divide(vector<int> &nums, int left, int right) { |
| if (left >= right) return 0; |
| int mid = left + ((right - left) >> 1); |
| int leftSum = divide(nums, left, mid); |
| int rightSum = divide(nums, mid + 1, right); |
| |
| int midSum = 0; |
| for (int l = left, r = mid + 1, sum = 0; l <= mid; ++l) { |
| while (r <= right && ((long) nums[l] > (long) 2 * nums[r])) { |
| sum++; |
| r++; |
| } |
| midSum += sum; |
| } |
| |
| merge(nums, left, mid, right); |
| return leftSum + midSum + rightSum; |
| } |
| |
| int reversePairs(vector<int> &nums) { |
| temp.resize(nums.size()); |
| return divide(nums, 0, nums.size() - 1); |
| } |
| }; |
本文作者:n1ce2cv
本文链接:https://www.cnblogs.com/sprinining/p/18432694
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律