1. 程式人生 > 其它 >2020/12/10 小和問題

2020/12/10 小和問題

技術標籤:c++資料結構與演算法c++

裡面有句抖機靈

		int mid = left + ((right - left) >> 1);

可以理解為

mid=(L+R)/2

但是這是一種不安全的寫法,因為可能(R+L)溢位
安全的寫法可以表示為:

mid=L+(R-L)/2;

而除以2就可以寫成“>>1”:二進位制右移一位
位運算的時間比常數運算要好


#include <iostream>
#include <vector>
#include <ctime>
using namespace std;

class CSmallSum
{ public: int smallSum(vector<int>& arr) { if (arr.size() < 2) { return 0; } return mergeSortProcess(arr, 0, arr.size() - 1); } private: int mergeSortProcess(vector<int>& arr, int left, int right) { if (left == right) { return 0; } int mid = left + ((right -
left) >> 1); return mergeSortProcess(arr, left, mid) + mergeSortProcess(arr, mid + 1, right) + merge(arr, left, mid, right); } int merge(vector<int>& arr, int left, int mid, int right) { int tmpL = left; int tmpR = mid + 1; int res = 0; vector<int> help; while
(tmpL <= mid && tmpR <= right) { // 生成小和的關鍵一步 res += arr.at(tmpL) < arr.at(tmpR) ? arr.at(tmpL) * (right - tmpR + 1) : 0; help.push_back(arr.at(tmpL) < arr.at(tmpR) ? arr.at(tmpL++) : arr.at(tmpR++)); } while (tmpL <= mid) { help.push_back(arr.at(tmpL++)); } while (tmpR <= right) { help.push_back(arr.at(tmpR++)); } for (int i = 0; i < help.size(); i++) { arr.at(left + i) = help.at(i); } return res; } }; int main() { vector<int> arr{ 1, 3, 4, 2, 5 }; int res = CSmallSum().smallSum(arr); cout << res << endl; system("pause"); return 0; }