分析:用歸併的 思想 可以將時間複雜度降爲 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++; } } };