分析:用归并的 思想 可以将时间复杂度降为 O(logN)
class Solution { public: int InversePairs(vector<int> data) { if (data.size() <= 1) return 0; return MergeSort(data, 0, data.size() - 1); } int MergeSort(vector<int> &data, int left, int right){ if (left == right) return 0; vector<int> arr; int arge = (left + right) / 2; int num1 = MergeSort(data, left, arge); int num2 = MergeSort(data, arge + 1, right); int count = 0; int i = right; int j = arge + 1; while (left <= arge && j<=right){ if (data[arge]>data[right]){ count += right - j + 1; arr.insert(arr.begin(), data[arge--]); } else{ arr.insert(arr.begin(), data[right--]); } } while (j <= right){ arr.insert(arr.begin(), data[right--]); } while (left <=arge){ arr.insert(arr.begin(), data[arge--]); } j = arr.size()-1; while (i >= left){ data[i--] = arr[j--]; } return count + num1 + num2; } };
分析:由链表结构看出为无环单链表
class Solution { public: ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) { if(pHead1==NULL||pHead2==NULL) return NULL; int len1=0,len2=0,tag=0; ListNode *tmp1=pHead1; ListNode *tmp2=pHead2; while(tmp1->next){ len1++; tmp1=tmp1->next; } while(tmp2->next){ len2++; tmp2=tmp2->next; } if(tmp1!=tmp2) return NULL; if(len1>len2){ len1=len1-len2; } else{ tag=1; len1=len2-len1; } tmp1=pHead1; tmp2=pHead2; while(tmp1||tmp2){ if(tag==0){ if(len1>0){ len1--; tmp1=tmp1->next; } if(tmp1==tmp2&&tmp1!=NULL) return tmp1; if(len1==0){ tmp1=tmp1->next; tmp2=tmp2->next; } } else{ if(len1>0){ len1--; tmp2=tmp2->next; } if(tmp1==tmp2&&tmp1!=NULL) return tmp1; if(len1==0){ tmp1=tmp1->next; tmp2=tmp2->next; } } } return NULL; } };
分析:1.很容易想到遍历一遍 计数的方法。时间复杂度为O(N);
2.用二分查找的方法,确定查找数的左边界和右边界,相减即个数,时间复杂度为O(logN)
class Solution {//一般方法 public: int GetNumberOfK(vector<int> data ,int k) { if(data.size()==0) return 0; int count=0,i=0; while(i<data.size()){ if(data[i++]==k) count++; } return count; } };
class Solution { public: int TreeDepth(TreeNode* pRoot) { if(pRoot==NULL) return 0; int num=1,ret1=0,ret2=0; ret1=TreeDepth(pRoot->left); ret2=TreeDepth(pRoot->right); num+=ret1>ret2? ret1:ret2; return num; } };
分析:1.将所有数依次异或,得到的值为那两个数的异或结果。
2.在该值中找到一位为1,记录是第几位
3.将这一位为1的数异或 并将这一位为0的数异或 得到只出现一次 的2个数
class Solution { public: void FindNumsAppearOnce(vector<int> data, int * num1, int * num2) { if (data.size() <= 1) return; int num = 0, i = 0, j = 0; while (i<data.size()){ num ^= data[i++]; } i = 0; while ((num & 1) == 0){ j++; num = num >> 1; } while (i<data.size()){ if (((data[i] >> j) & 1) == 1) *num1 ^= data[i]; else *num2 ^= data[i]; i++; } } };