剑指offer系列28:数组中的逆序对
这个题我拿到没什么好的思路,除了一个个求的方法之外想不出效率更高的方法。这个题看剑指offer的意思是按照归并排序的方法做的,顺便复习一下归并排序^_^。看到这个题只要能想到用归并排序的方法做就已经成功了一半了,其次就是一些细节问题。写代码,你又思路,又会将思路用代码写出来才可以。只有思路不会写代码也不行。写代码的时候一定要认真仔细,养成良好的习惯,尽量在写的时候就少出错误,因为修改起来要找到错误并非易事。还有就是不要将问题想得太复杂,不用自己吓唬自己。认真,仔细,这道题有一些点很值得借鉴。特别是对与两个vector的相互之间的关系的处理,就是我备注的那一行,很巧妙的将一个vectoe的数据变化给了另一个vector。
1 #include<iostream> 2 #include <vector> 3 #include <iterator> 4 using namespace std; 5 class Solution { 6 public: 7 int InversePairs(vector<int> data) { 8 9 int len = data.size(); 10 if (len<= 0) 11 return 0; 12 vector<int> auxi(len); 13 for (int i = 0; i < len; i++)//这个循环很有用,因为你看后面24行的复制语句其实根据它的函数调用来看是反过来的 14 { 15 auxi[i] = data[i]; 16 } 17 long long re = InverseCore(data, auxi, 0, len - 1);//一定要设置成long long,否则只能通过一半测试用例 18 return re % 1000000007; 19 } 20 long long InverseCore(vector<int> &v, vector<int> &temp, int start, int end) 21 { 22 if (start == end) 23 { 24 temp[start] = v[start];//这一句其实可以不用,因为前面的13行for循环已经给它赋值过了 25 return 0; 26 } 27 int length = (end - start) / 2; 28 long long left = InverseCore(temp,v,start,start+length);//看清楚这里的函数调用,之所以这样写是要把上一次递归中对它做的改变给记录上去 29 long long right= InverseCore(temp,v,start+length+1,end); 30 31 int i = start+length;//记住这种中值数一定是由两部分构成的,因为start不一定只从0开始 32 int j = end; 33 int k = end; 34 long long count = 0; 35 while (i >= start&&j >= length + start + 1) 36 { 37 if (v[i] > v[j]) 38 { 39 temp[k--] = v[i--]; 40 count += j - length-start; 41 } 42 else 43 temp[k--] = v[j--]; 44 } 45 for (; i >= start; i--) 46 temp[k--] = v[i];//这里循环里又i--了就不用再减了 47 for (; j >= length + start + 1; j--) 48 temp[k--] = v[j]; 49 return left + right + count; 50 } 51 }; 52 int main() 53 { 54 Solution so; 55 vector<int> test{ 7,5,6,4 }; 56 cout << so.InversePairs(test) << endl; 57 return 0; 58 }
最后说一点,写代码一定要静下心。好好理清楚思路,写的时候每一步都想清楚为什么,大框架要清楚,小细节也不能忽视。