├── 1.txt ├── BigInteger.cpp ├── CircularQueue.cpp ├── ClosestPairOfPoint.cpp ├── CombinationPermutation.cpp ├── DP.cpp ├── FindMajority.cpp ├── Graph.cpp ├── HashTable.cpp ├── HashTableLinkedList.cpp ├── HeapMaintainMedian.cpp ├── HeapSort_Priority_queue.cpp ├── Heap_Sort.cpp ├── Heap_Sort_Big.cpp ├── HighFrequency.cpp ├── LinkedList.cpp ├── LinkedListUsingArray.cpp ├── QueueUsingStack.cpp ├── README.md ├── RedBlackTree.cpp ├── ReferenceCount.cpp ├── Search.cpp ├── SegmentTree.cpp ├── ShortestPathDijkstra.cpp ├── ShortestPathFloyd.cpp ├── Sorting.cpp ├── StackUsingQueue.cpp ├── StackWithMin.cpp ├── String.cpp ├── Tree.cpp ├── UnionFind.cpp ├── advanced ├── RedBlackTree.cpp ├── SegmentTree.cpp ├── SuffixArray.cpp ├── Trie.cpp ├── UnionFind.cpp └── uf.txt ├── bst_in.txt ├── code_on_paper.ppt ├── input.txt ├── test.cpp └── uf.txt /1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunwaylive/five-minutes-algorithm/a9593cf459ebba0145b89271616b6fb249b2d17d/1.txt -------------------------------------------------------------------------------- /BigInteger.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int N = 210; 5 | char str1[N], str2[N]; 6 | int num1[N], num2[N], num3[N]; 7 | int num4[N * 2];// for multiple 8 | 9 | //************************************************************ 10 | //default num1 , num2 >=0 11 | void add(int num1[], int num2[], int num3[]){ 12 | for(int i = 0; i < N; ++i) 13 | num3[i] = 0; 14 | 15 | for(int i = 0; i < N; ++i){ 16 | num3[i] = num1[i] + num2[i] + num3[i];//add num3 itself 17 | if(num3[i] >= 10){ 18 | num3[i] -= 10; 19 | num3[i + 1]++;//num3 itself store the carry bit 20 | } 21 | } 22 | } 23 | 24 | //************************************************************ 25 | //default num1 >= num2 >=0 26 | void sub(int num1[], int num2[], int num3[]){ 27 | for(int i = 0; i < N; ++i) 28 | num3[i] = 0; 29 | 30 | for(int i = 0; i < N; ++i){ 31 | num3[i] = num1[i] - num2[i] + num3[i]; 32 | if(num3[i] < 0){ 33 | num3[i] += 10; 34 | num3[i + 1]--; 35 | } 36 | } 37 | } 38 | 39 | //************************************************************ 40 | //O(n^2) 41 | //default num1 , num2 >=0 42 | void multiple(int num1[], int num2[], int num3[]){ 43 | for(int i = 0; i < N * 2; ++i)//size of num3 is twice of num1 and num2 44 | num3[i] = 0; 45 | 46 | for(int i = 0; i < N; ++i){ 47 | for(int j = 0; j < N; ++j){ 48 | num3[i + j] = num1[i] * num2[j] + num3[i + j]; 49 | if(num3[i + j] >= 10){ 50 | num3[i + j + 1] += num3[i + j] / 10; 51 | num3[i + j] %= 10; 52 | } 53 | } 54 | } 55 | } 56 | 57 | //************************************************************ 58 | void print(int num[]){ 59 | int i, j; 60 | 61 | for(i = N - 1; i >= 0 && num[i] == 0; --i) 62 | ; 63 | if(i == -1){ 64 | cout<<0; 65 | }else{ 66 | for(j = i; j >= 0; --j){ 67 | cout<>str1>>str2; 76 | memset(num1, 0, sizeof(num1)); 77 | memset(num2, 0, sizeof(num2)); 78 | const int str1_len = strlen(str1); 79 | const int str2_len = strlen(str2); 80 | int i, j; 81 | j = 0; 82 | for(i = str1_len - 1; i >= 0; --i){ 83 | num1[j++] = str1[i] - '0'; 84 | } 85 | j = 0; 86 | for(i = str2_len - 1; i >= 0; --i){ 87 | num2[j++] = str2[i] - '0'; 88 | } 89 | 90 | //1. add 91 | add(num1, num2, num3); 92 | print(num3); 93 | 94 | //2. sub 95 | int sign = strcmp(str1, str2); 96 | if (sign >= 0){ 97 | sub(num1, num2, num3); 98 | }else{ 99 | sub(num2, num1, num3); 100 | } 101 | if(sign < 0) cout<<"-"; 102 | print(num3); 103 | 104 | //3. multiple 105 | multiple(num1, num2, num4); 106 | print(num4); 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /CircularQueue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int MAX_LEN = 10; 5 | 6 | class CircularQueue{ 7 | public: 8 | CircularQueue(int len); 9 | ~CircularQueue(); 10 | 11 | bool push(int key); 12 | void pop(); 13 | int front(); 14 | bool empty(); 15 | 16 | private: 17 | int m_front, m_rear; 18 | int m_len; 19 | int *m_elems; 20 | }; 21 | 22 | CircularQueue::CircularQueue(int len){ 23 | m_len = len; 24 | m_elems = new int[len]; 25 | m_front = 0, m_rear = 0; 26 | } 27 | 28 | CircularQueue::~CircularQueue(){ 29 | delete m_elems; 30 | } 31 | 32 | bool CircularQueue::push(int key){ 33 | if((m_rear + 1) % m_len == m_front){ 34 | return false; 35 | }else{ 36 | m_elems[m_rear] = key; 37 | m_rear = (m_rear + 1) % m_len; 38 | return true; 39 | } 40 | } 41 | 42 | void CircularQueue::pop(){ 43 | if(m_rear == m_front){ 44 | return; 45 | }else{ 46 | m_front = (m_front + 1) % m_len; 47 | } 48 | } 49 | 50 | int CircularQueue::front(){ 51 | if(m_rear == m_front){ 52 | return INT_MAX; 53 | }else{ 54 | return m_elems[m_front]; 55 | } 56 | } 57 | 58 | bool CircularQueue::empty(){ 59 | return m_rear == m_front; 60 | } 61 | 62 | int main(){ 63 | CircularQueue cq(MAX_LEN); 64 | int n = 7; 65 | while(n--){ 66 | int tmp = rand() % 50; 67 | cq.push(tmp); 68 | cout<<"push: " < 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | //************************************************************ 7 | //1 D closet pair 8 | int closestPairOfPoint1DHelper(int x[], int n, int start, int end){ 9 | int k = end - start; 10 | if(k == 1) return INT_MAX; 11 | else if(k == 2) return x[start + 1] - x[start]; 12 | 13 | int mid = start + ((end - start) >> 1); 14 | int l = closestPairOfPoint1DHelper(x, n, start, mid); 15 | int r = closestPairOfPoint1DHelper(x, n, mid, end); 16 | int d = min(l, r); 17 | //左闭右开,左边半段没算到 18 | d = min(d, x[mid] - x[mid - 1]); 19 | return d; 20 | } 21 | 22 | int closestPairOfPoint1D(int x[], int n){ 23 | sort(x, x + n); 24 | return closestPairOfPoint1DHelper(x, n, 0, n); 25 | } 26 | 27 | // int main() 28 | // { 29 | // int a[] = {4, 5, 8}; 30 | // const int n = sizeof(a) / sizeof(*a); 31 | // cout<> 1); 62 | double l = closestPairOfPoint2D(start, mid); 63 | double r = closestPairOfPoint2D(mid, end); 64 | double d = min(l, r); 65 | 66 | //find points in the vertical strip 67 | vector t; 68 | for(int i = start; i < end; ++i){ 69 | if((p[i].x - p[mid].x) <= d) 70 | t.push_back(i); 71 | } 72 | sort(t.begin(), t.end(), cmp2);//sort y-coord in Ascending order 73 | 74 | //update the minimum distance 75 | int c = t.size(); 76 | for(int i = 0; i < c; ++i){ 77 | for(int j = 1; j <= 7 && i + j < c; ++j){//easy proved, see stanford course 78 | double td = dist(p[i + j], p[i]); 79 | d = min(d, td); 80 | } 81 | } 82 | return d; 83 | } 84 | 85 | int main(){ 86 | int n; 87 | while(scanf("%d\n", &n) && n){ 88 | for(int i = 0; i < n; ++i){ 89 | scanf("%d %d", &p[i].x, &p[i].y); 90 | } 91 | sort(p, p + n, cmp1);// sort by x-coord 92 | double dist = closestPairOfPoint2D(0, n); 93 | if(dist > 10000) cout<< "INFINITY"< 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | //given a array, get all permutations; no duplicates in the array 9 | //https://oj.leetcode.com/problems/permutations/ 10 | void permutation_helper(vector &num, vector > &result, vector &path){ 11 | if(path.size() == num.size()){ 12 | result.push_back(path); 13 | } 14 | for(int i = 0; i < num.size(); ++i){ 15 | vector::iterator iter = find(path.begin(), path.end(), num[i]); 16 | if(iter == path.end()){ 17 | path.push_back(num[i]); 18 | permutation_helper(num, result, path); 19 | path.pop_back(); 20 | } 21 | } 22 | } 23 | 24 | vector > permutation(vector &num){ 25 | vector > result; 26 | if(num.empty()) return result; 27 | 28 | sort(num.begin(), num.end());//important! 29 | vector path; 30 | permutation_helper(num, result, path); 31 | return result; 32 | } 33 | 34 | //******************************************************************************** 35 | //given a array, get all permutations; duplicates exist in the array 36 | //https://oj.leetcode.com/problems/permutations-ii/ 37 | void permutation_helper2(vector &num, vector &visited, vector > &result, vector &path){ 38 | if(path.size() == num.size()){ 39 | result.push_back(path); 40 | } 41 | 42 | for(int i = 0; i < num.size(); ++i){ 43 | //later half mean: the same state has been searched by the former letter 44 | if(visited[i] || (i - 1>= 0 && num[i - 1] == num[i] && !visited[i - 1])){ 45 | continue; 46 | } 47 | visited[i] = true; 48 | path.push_back(num[i]); 49 | permutation_helper2(num, visited, result, path); 50 | path.pop_back(); 51 | visited[i] = false; 52 | } 53 | } 54 | 55 | vector > permutation2(vector &num){ 56 | vector > result; 57 | if(num.empty()) return result; 58 | 59 | sort(num.begin(), num.end());//important! 60 | vector visited(num.size(), false); 61 | vector path; 62 | permutation_helper2(num, visited, result, path); 63 | return result; 64 | } 65 | 66 | //************************************************************ 67 | vector next_permutation(vector num){ 68 | if(num.empty()) return num; 69 | 70 | int len = num.size(); 71 | int i = -1; 72 | for(i = len - 2; i >= 0; --i){ 73 | if(num[i] < num[i + 1]) 74 | break; 75 | } 76 | 77 | if(i == -1) return num; 78 | int pivot = i; 79 | for(i = len - 1; i >= pivot; --i){ 80 | if(num[i] > num[pivot]) 81 | break; 82 | } 83 | swap(num[pivot], num[i]); 84 | reverse(num.begin() + pivot + 1, num.end()); 85 | return num; 86 | } 87 | 88 | //************************************************************ 89 | //given n:1 ~ 9, find the k-th permutation 90 | string getPermutation(int n, int k){ 91 | const int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};//9 numbers, start from 0 92 | vector visited(10, false);//1 ~ n 93 | 94 | string ans(n, '0'); 95 | int i, j, t; 96 | --k;// 前面需要有k-1个排列 97 | for(i = 0; i < n; ++i){ 98 | t = k / fac[n - 1 -i];//there should be t numbers less than number at i-th position 99 | //find the t-th unused number 100 | for(j = 1; j <= n; ++j){ 101 | if(!visited[j]){ 102 | if(t < 0){ 103 | break; 104 | }else{ 105 | --t; 106 | } 107 | }//end if 108 | }//end for 109 | ans[i] += j; 110 | visited[j] = true; 111 | }//end for 112 | return ans; 113 | } 114 | 115 | //************************************************************ 116 | //Combination, is also subsets 117 | //http://answer.ninechapter.com/solutions/subsets/ 118 | //no duplicates in number 119 | void subsets_helper(vector &num, vector > &result, vector &path, int pos){ 120 | result.push_back(path); 121 | 122 | for(int i = pos; i < num.size(); ++i){ 123 | path.push_back(num[i]); 124 | subsets_helper(num, result, path, i + 1);//i 代表当前数加或者不加,i + 1代表考虑下一个数 125 | path.pop_back(); 126 | } 127 | } 128 | 129 | vector > subsets(vector num){ 130 | vector > result; 131 | if(num.empty()) return result; 132 | 133 | sort(num.begin(), num.end()); 134 | vector path; 135 | subsets_helper(num, result, path, 0); 136 | return result; 137 | } 138 | 139 | //************************************************************ 140 | void subsets_helper2(vector &num, vector > &result, vector &path, int pos){ 141 | result.push_back(path); 142 | 143 | for(int i = pos; i < num.size(); ++i){ 144 | if(i > pos && num[i] == num[i - 1]){ 145 | continue; 146 | } 147 | path.push_back(num[i]); 148 | subsets_helper2(num, result, path, i + 1); 149 | path.pop_back(); 150 | } 151 | } 152 | 153 | vector > subsets2(vector num){ 154 | vector > result; 155 | if(num.empty()) return result; 156 | 157 | sort(num.begin(), num.end()); 158 | vector path; 159 | subsets_helper2(num, result, path, 0); 160 | return result; 161 | } 162 | 163 | //************************************************************ 164 | //https://oj.leetcode.com/problems/combination-sum-ii/ 165 | //each element can be used only once 166 | void combinationSum_helper(vector &candidates, vector > &result, vector &path, int sum, int pos){ 167 | if(sum < 0) return; 168 | if(sum == 0){ 169 | result.push_back(path); 170 | } 171 | 172 | int prev = -1; 173 | for(int i = pos; i < candidates.size(); ++i){ 174 | if(candidates[i] == prev) continue;//同一次扩展中如何和之前重复则跳过 175 | 176 | path.push_back(candidates[i]); 177 | sum -= candidates[i]; 178 | combinationSum_helper(candidates, result, path, sum, i + 1); 179 | prev = candidates[i];//important 180 | path.pop_back(); 181 | sum += candidates[i]; 182 | } 183 | } 184 | 185 | vector > combinationSum(vector &candidates, int target){ 186 | vector > result; 187 | if(candidates.empty()) return result; 188 | 189 | sort(candidates.begin(), candidates.end()); 190 | vector path; 191 | combinationSum_helper(candidates, result, path, target, 0); 192 | return result; 193 | } 194 | 195 | //************************************************************ 196 | // 2https://oj.leetcode.com/problems/combination-sum/ 197 | // number can be used many times 198 | void combinationSum_helper2(vector &candidates, vector > &result, vector &path, int sum, int pos){ 199 | if(sum < 0) return; 200 | if(sum == 0) result.push_back(path); 201 | 202 | for(int i = pos; i < candidates.size(); ++i){ 203 | path.push_back(candidates[i]); 204 | sum -= candidates[i]; 205 | combinationSum_helper2(candidates, result, path, sum, i);//next is i, duplicates allowed 206 | sum += candidates[i]; 207 | path.pop_back(); 208 | } 209 | } 210 | 211 | vector > combinationSum2(vector &candidates, int target){ 212 | vector > result; 213 | if(candidates.empty()) return result; 214 | 215 | vector path; 216 | combinationSum_helper2(candidates, result, path, target, 0);//begin at position 0 217 | return result; 218 | } 219 | 220 | //************************************************************ 221 | //http://blog.csdn.net/yanghao58686763/article/details/1812418 222 | vector grayCode(int n){ 223 | vector code; 224 | code.resize(pow(2, n)); 225 | 226 | if(n == 1){ 227 | code[0] = string("0"); 228 | code[1] = string("1"); 229 | return code; 230 | } 231 | 232 | vector last = grayCode(n - 1); 233 | for(int i = 0; i < last.size(); ++i){ 234 | code[i] = "0" + last[i]; 235 | code[code.size() - 1 - i] = last[i] + "1"; 236 | } 237 | return code; 238 | } 239 | 240 | //******************************************************************************** 241 | template 242 | void printMatrix(vector > matrix){ 243 | for(int i = 0; i < matrix.size(); ++i){ 244 | for(int j = 0; j < matrix[i].size(); ++j){ 245 | cout< &result) { 262 | if (path.size() == origin.size()) { 263 | result.push_back(path); 264 | return; 265 | } 266 | 267 | for (int i = 0; i < intermedian.size(); ++i) { 268 | // core, select one in the left 269 | path.push_back(intermedian[i]); 270 | 271 | string tmp = intermedian; 272 | tmp.erase(i, 1); 273 | // pass left to the next round 274 | StrPermHelper(origin, tmp, path, result); 275 | 276 | // core 277 | path.pop_back(); 278 | } 279 | } 280 | 281 | vector StrPerm(string str) { 282 | vector result; 283 | string path; 284 | StrPermHelper(str, str, path, result); 285 | return result; 286 | } 287 | 288 | /* Combination of a string 289 | POBLEM: 290 | Implement a function that prints all possible combinations of the 291 | characters in a string. These combinations range in length from one to the length 292 | of the string. Two combinations that differ only in ordering of their characters are 293 | the same combination. In other words, “12” and “31” are different combinations 294 | from the input string “123”, but “21” is the same as “12”. 295 | characters in a string. These combinations range in length from one to the length 296 | of the string. Two combinations that differ only in ordering of their characters are 297 | the same combination. In other words, “12” and “31” are different combinations 298 | from the input string “123”, but “21” is the same as “12”. */ 299 | void StrCombHelper(string &origin, int level, string &path, vector &result) { 300 | if (path.size() > 0) { 301 | result.push_back(path); 302 | } 303 | 304 | for (int i = level; i < origin.size(); ++i) { 305 | path.push_back(origin[i]); 306 | StrCombHelper(origin, i + 1, path, result); 307 | path.pop_back(); 308 | } 309 | } 310 | 311 | vector StrComb(string str) { 312 | vector result; 313 | string path; 314 | 315 | StrCombHelper(str, 0, path, result); 316 | 317 | return result; 318 | } 319 | 320 | /* telephone num problem*/ 321 | std::unordered_map tel_dict = {{'2', "ABC"}, 322 | {'3', "DEF"}, 323 | {'4', "GHI"}, 324 | {'5', "JKL"}, 325 | {'6', "MNO"}, 326 | {'7', "PRS"}, 327 | {'8', "TUV"}, 328 | {'9', "WXY"}}; 329 | 330 | char GetCharKey(char tel_key, int place) { 331 | return tel_dict[tel_key][place]; 332 | } 333 | 334 | void TelWordsHelper(string &tel_num, int level, string path, 335 | vector &result) { 336 | if (path.size() == tel_num.size()) { 337 | result.push_back(path); 338 | cout << "push " << "level: " << level << endl; 339 | return; 340 | } 341 | 342 | // we don't need for loop here, combination or permutation need, but NOT this 343 | // because combination/permutation have their own way to place each element 344 | // here we just need to go through all tel_num 345 | if (tel_num[level] == '0' || tel_num[level] == '1' || tel_num[level] == '-') { 346 | path.push_back(tel_num[level]); 347 | TelWordsHelper(tel_num, level + 1, path, result); 348 | } else { 349 | for (int j = 0; j < 3; ++j) { 350 | path.push_back(GetCharKey(tel_num[level], j)); 351 | TelWordsHelper(tel_num, level + 1, path, result); 352 | path.pop_back(); 353 | } 354 | } 355 | } 356 | 357 | vector TelWords(string tel_num) { 358 | vector result; 359 | string path; 360 | TelWordsHelper(tel_num, 0, path, result); 361 | return result; 362 | } 363 | 364 | vector TelWordsIterative(string tel_num) { 365 | vector result; 366 | string path; 367 | // get replaced string using place = 1 368 | for (int i = 0; i < tel_num.size(); ++i) { 369 | if (tel_num[i] == '0' || tel_num[i] == '1' || tel_num[i] == '-') { 370 | path.push_back(tel_num[i]); 371 | } else { 372 | path.push_back(GetCharKey(tel_num[i], 1 - 1)); 373 | } 374 | } 375 | 376 | // this is kinda new way of thinking, new code structure 377 | // a while + a for + a state machine 378 | while (true) { 379 | result.push_back(path); 380 | 381 | for (int i = tel_num.size() - 1; i >= -1; --i) { 382 | if (i == -1) { 383 | return result; 384 | } 385 | 386 | // simple state machine 387 | if (path[i] == '0' || path[i] == '1' ||path[i] == '-') { 388 | continue; 389 | } else if (path[i] == GetCharKey(tel_num[i], 3 - 1)) { 390 | // if we have gone all 3 states, we should move to next level, 391 | // before move to next level, we need RESET to place 1 state, 392 | // because when next level state changes, cur level should also 393 | // go through 3 states 394 | path[i] = GetCharKey(tel_num[i], 1 - 1); 395 | continue; 396 | } else if (path[i] == GetCharKey(tel_num[i], 1 - 1)) { 397 | path[i] = GetCharKey(tel_num[i], 2 - 1); 398 | break; 399 | } else if (path[i] == GetCharKey(tel_num[i], 2 - 1)) { 400 | path[i] = GetCharKey(tel_num[i], 3 - 1); 401 | break; 402 | } 403 | } 404 | } 405 | return result; 406 | } 407 | 408 | /***************** test case ************************/ 409 | int main(){ 410 | string str("2-2"); 411 | vector result = TelWordsIterative(str); 412 | cout << result.size() << endl; 413 | for(int i = 0; i < result.size(); ++i) { 414 | cout << result[i] << endl; 415 | } 416 | cout< 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | //************************************************************ 9 | int longestCommonSubstring(const string &txt, const string &query){ 10 | if(txt.empty() || query.empty()) return 0; 11 | 12 | int t_len = txt.length(); 13 | int q_len = query.length(); 14 | vector tmp(t_len, 0), result(t_len, 0); 15 | int max_end = 0, max_len = 0; 16 | 17 | for(int i = 0; i < q_len; ++i){ 18 | tmp.assign(t_len, 0);//clear every time 19 | for(int j = 0; j < t_len; ++j){ 20 | if(query[i] == txt[j]){ 21 | if(j == 0) tmp[j] = 1; 22 | else tmp[j] = result[j - 1] + 1; 23 | } 24 | 25 | if(tmp[j] > max_len){ 26 | max_len = tmp[j]; 27 | max_end = j; 28 | } 29 | }// end for 30 | swap(tmp, result); 31 | }//end for 32 | //string s = txt.substr(max_end - max_len + 1, max_len); //获得子串 33 | return max_len; 34 | } 35 | 36 | //************************************************************ 37 | //http://blog.csdn.net/yysdsyl/article/details/4226630 38 | void getMaxSequence(const string &pat, vector > &b, int i, int j){ 39 | if(i == 0 || j == 0) return; 40 | 41 | if(b[i][j] == 0){ 42 | getMaxSequence(pat, b, i - 1, j - 1); 43 | cout< > c(p_len + 1, vector(t_len + 1, 0)); 55 | vector > b(p_len + 1, vector(t_len + 1, 0)); 56 | //first row and first column is 0, dp starts from second row and second column 57 | int max_len = 0; 58 | for(int i = 1; i <= p_len; ++i){ 59 | for(int j = 1; j <= t_len; ++j){ 60 | if(txt[j - 1] == pat[i - 1]){ 61 | c[i][j] = c[i - 1][j - 1] + 1; 62 | b[i][j] = 0; 63 | }else if(c[i - 1][j] > c[i][j - 1]){ 64 | c[i][j] = c[i - 1][j]; 65 | b[i][j] = 1; 66 | }else { 67 | c[i][j] = c[i][j - 1]; 68 | b[i][j] = -1; 69 | } 70 | } 71 | } 72 | 73 | max_len = c[p_len][t_len]; 74 | //get the max sequence 75 | getMaxSequence(pat, b, p_len, t_len); 76 | return max_len; 77 | } 78 | //------------------------------------------------------------ 79 | int max_6(int a1, int a2, int a3, int a4, int a5, int a6){ 80 | return max(a1, max(a2, max(a3, max(a4, max(a5, a6))))); 81 | } 82 | 83 | int lcsubsequence3(const string &str1, const string &str2, const string &str3){ 84 | int l1 = str1.length(); 85 | int l2 = str2.length(); 86 | int l3 = str3.length(); 87 | vector > > c(l1 + 1, vector > (l2 + 1, vector(l3 + 1, 0))); 88 | for(int i = 1; i <= l1; ++i){ 89 | for(int j = 1; j <= l2; ++j){ 90 | for(int k = 1; k <= l3; ++k){ 91 | if(str1[i - 1] == str2[j - 1] && str2[j - 1] == str3[k - 1]){ 92 | c[i][j][k] = c[i - 1][j - 1][k - 1] + 1; 93 | }else if(str1[i - 1] == str2[j - 1] && str1[i - 1] != str3[k - 1]){ 94 | c[i][j][k] = max(c[i][j][k - 1], c[i - 1][j - 1][k]); 95 | }else if(str1[i - 1] == str3[j - 1] && str1[i - 1] != str2[k - 1]){ 96 | c[i][j][k] = max(c[i][j - 1][k], c[i - 1][j][k - 1]); 97 | }else if(str2[j - 1] == str3[k - 1] && str2[j - 1] != str1[i - 1]){ 98 | c[i][j][k] = max(c[i - 1][j][k], c[i][j - 1][k - 1]); 99 | }else{ 100 | c[i][j][k] = max_6(c[i - 1][j][k], c[i][j - 1][k], c[i][j][k - 1], 101 | c[i - 1][j - 1][k], c[i][j - 1][k - 1], c[i - 1][j][k - 1]); 102 | } 103 | } 104 | } 105 | } 106 | return c[l1][l2][l3]; 107 | } 108 | 109 | 110 | //************************************************************ 111 | //http://blog.csdn.net/wangkechuang/article/details/7949151 112 | //longest increasing sequence 113 | 114 | //O(n^2) 115 | //dp[i] 表示以第i个数结尾的LIS的长度,必须包含i 116 | int LIS(int *a, int n){ 117 | if(a == NULL) return 0; 118 | 119 | int max_len = 0; 120 | int *dp = new int[n + 1](); 121 | dp[1] = 1; 122 | for(int i = 2; i <= n; ++i){ 123 | for(int j = 1; j < i; ++j){ 124 | if(a[j - 1] < a[i - 1] && dp[j] + 1 > dp[i])//大于当前的最大值 125 | dp[i] = dp[j] + 1; 126 | } 127 | max_len = max(max_len, dp[i]); 128 | } 129 | delete[] dp; 130 | return max_len; 131 | } 132 | 133 | int LDS(int *a, int n){ 134 | if(a == NULL) return 0; 135 | 136 | int max_len = 0; 137 | int *dp = new int[n + 1]; 138 | dp[1] = 1; 139 | for(int i = 2; i <= n; ++i){ 140 | for(int j = 1; j < i; ++j){ 141 | if(a[j - 1] >= a[i - 1] && dp[j] + 1 > dp[i]){ 142 | dp[i] = dp[j] + 1; 143 | } 144 | } 145 | max_len = max(max_len, dp[i]); 146 | } 147 | delete[] dp; 148 | return max_len; 149 | } 150 | 151 | //************************************************************ 152 | //https://oj.leetcode.com/problems/maximum-subarray/ 153 | //maximum sum subarray 154 | int maxSubArray(int *a, int n){ 155 | assert(a != NULL); 156 | 157 | int max_sum = 0; 158 | int cur_sum = 0; 159 | int start = -1, end = -1; 160 | for(int i = 0; i < n; ++i){ 161 | cur_sum += a[i]; 162 | if(cur_sum < 0){ 163 | start = i + 1; 164 | cur_sum = 0; 165 | } 166 | 167 | if(cur_sum > max_sum){ 168 | max_sum = cur_sum; 169 | end = i; 170 | } 171 | } 172 | cout< 0 ? (a[i - 1] + a[i]) : a[i]; 184 | max_sum = max(max_sum, a[i]); 185 | } 186 | return max_sum; 187 | } 188 | 189 | //O(nlogn) 190 | int maxSubArray3(int *a, int start, int end){ 191 | assert(a != NULL); 192 | if(start + 1 < end){ 193 | int mid = start + ((end - start) >> 1); 194 | int left = maxSubArray3(a, start, mid); 195 | int right = maxSubArray3(a, mid + 1, end); 196 | 197 | //left part 198 | int l = 0, m_l = 0; 199 | for(int i = mid - 1; i >= start; --i){ 200 | l += a[i]; 201 | m_l = max(m_l, l); 202 | } 203 | //right part 204 | int r = 0, m_r = 0; 205 | for(int i = mid; i < end; ++i){ 206 | r += a[i]; 207 | m_r = max(m_r, r); 208 | } 209 | // compare 3 210 | return max(left, max(right, m_l + m_r)); 211 | }else{//only one element 212 | return max(0, a[start]); 213 | } 214 | } 215 | 216 | //************************************************************ 217 | //Find the contiguous subarray within an array (containing at least one number) 218 | //which has the largest product. 219 | //For example, given the array [2,3,-2,4], 220 | //the contiguous subarray [2,3] has the largest product = 6. 221 | //http://www.geeksforgeeks.org/maximum-product-subarray/ in the comment 222 | int maxProduct(int A[], int n) { 223 | if (n == 0) return 0; 224 | int maxProduct = A[0]; 225 | int minProduct = A[0]; 226 | int maxRes = A[0]; 227 | for (int i = 1; i < n; i++) 228 | { 229 | if (A[i] >= 0) 230 | { 231 | maxProduct = max(maxProduct * A[i], A[i]); 232 | minProduct = min(minProduct * A[i], A[i]); 233 | } 234 | else 235 | { 236 | int oldmax = maxProduct; 237 | maxProduct = max(minProduct * A[i], A[i]); 238 | minProduct = min(oldmax * A[i], A[i]); 239 | } 240 | maxRes = max(maxRes, maxProduct); 241 | } 242 | return maxRes; 243 | } 244 | 245 | //************************************************************ 246 | //insert delete replace 247 | int editDistance(const string &txt, const string &pat){ 248 | int t_len = txt.length(); 249 | int p_len = pat.length(); 250 | vector > c(p_len + 1, vector(t_len + 1, 0)); 251 | for(int i = 0; i <= p_len; ++i){ 252 | c[i][0] = i; 253 | } 254 | for(int j = 0; j <= t_len; ++j){ 255 | c[0][j] = j; 256 | } 257 | 258 | for(int i = 1; i <= p_len; ++i){ 259 | for(int j = 1; j <= t_len; ++j){ 260 | if(pat[i - 1] == txt[j - 1]){ 261 | c[i][j] = c[i - 1][j - 1]; 262 | }else{ 263 | c[i][j] = min(c[i - 1][j - 1], min(c[i][j - 1], c[i - 1][j])) + 1; 264 | } 265 | } 266 | } 267 | return c[p_len][t_len]; 268 | } 269 | 270 | //************************************************************ 271 | //https://oj.leetcode.com/problems/triangle/ 272 | int minimumTotal(vector > &triangle){ 273 | int row = triangle.size(); 274 | vector tmp(row, 0); 275 | vector sum(row, 0); 276 | for(int i = 0; i < row; ++i){ 277 | sum.assign(row, 0); 278 | for(int j = 0; j <= i; ++j){ 279 | if(j == 0){ 280 | sum[j] = triangle[i][j] + tmp[j]; 281 | }else if(j == i){ 282 | sum[j] = triangle[i][j] + tmp[j - 1]; 283 | }else{ 284 | sum[j] = min(tmp[j], tmp[j - 1]) + triangle[i][j]; 285 | } 286 | } 287 | swap(tmp, sum); 288 | } 289 | 290 | //result saved in tmp 291 | int min_sum = INT_MAX; 292 | for(int i = 0; i < row; ++i){ 293 | cout<<"sum[i]: " < > dp(n, vector(n, false)); 307 | for(int i = 0; i < n; ++i){ 308 | int l, r; 309 | //search odd 310 | l = i - 1, r = i + 1; 311 | while(l >= 0 && r <= n && str[l] == str[r]){ 312 | dp[l][r] = true; 313 | l--, r++; 314 | } 315 | //search even 316 | l = i - 1, r = i; 317 | while(l >= 0 && r <= n && str[l] == str[r]){ 318 | dp[l][r] = true; 319 | l--, r++; 320 | } 321 | } 322 | 323 | //core part 324 | //count[i]: (i ~ end)'s min cut; count[i] = min(count[j] + 1) j: i ~ end 325 | //answer: count[0] 326 | vector cut(n + 1, 0); 327 | for(int i = n - 1; i >= 0; --i){ 328 | cut[i] = n - i; 329 | for(int j = i; j < n; ++j){//j can be equal to i, just one letter 330 | if(dp[i][j] == 1){ 331 | cut[i] = min(cut[i], cut[j + 1] + 1); 332 | } 333 | } 334 | } 335 | return cut[0] - 1; 336 | } 337 | 338 | //************************************************************ 339 | //贪心法活动选择。活动已经按照结束时间从早到晚 排好序, P225 340 | //若未排序,则:http://blog.csdn.net/crescent__moon/article/details/8828241 341 | vector selectActivity(int *s, int *f, int n){ 342 | vector result; 343 | if(s == NULL || f == NULL) return result; 344 | 345 | //第一个必选 346 | result.push_back(0); 347 | int last_end = f[0]; 348 | for(int i = 0; i < n; ++i){ 349 | if(s[i] >= last_end){ //找到余下合理活动中最早结束的那个,合理的意思是 在上一个活动结束后开始。记住 已经排好序 350 | result.push_back(i); 351 | last_end = f[i]; 352 | } 353 | } 354 | cout<= 0; --j){ 363 | cout< > c(n, vector(n, 0)); 379 | c[0][0] = e0 + a0[0]; 380 | c[1][0] = e1 + a1[0]; 381 | for(int j = 1; j < n; ++j){ 382 | c[0][j] = min(c[0][j - 1], c[1][j - 1] + t1[j - 1]) + a0[j]; 383 | c[1][j] = min(c[1][j - 1], c[0][j - 1] + t0[j - 1]) + a1[j]; 384 | //update l0 385 | if(c[0][j - 1] < c[1][j - 1] + t1[j - 1]) l0[j] = 0; 386 | else l0[j] = 1; 387 | 388 | //update l1 389 | if(c[1][j - 1] < c[0][j - 1] + t0[j - 1]) l1[j] = 1; 390 | else l1[j] = 0; 391 | } 392 | 393 | if(c[0][n - 1] + x0 < c[1][n - 1] + x1) printWay(l0, l1, n, 0); 394 | else printWay(l0, l1, n, 1); 395 | 396 | delete[] l0; 397 | delete[] l1; 398 | return min(c[0][n - 1] + x0, c[1][n - 1] + x1); 399 | } 400 | 401 | //test program 402 | // int a1[] = {7, 9, 3, 4, 8, 4}; 403 | // int a2[] = {8, 5, 6, 4, 5, 7}; 404 | // int line_len = sizeof(a1) / sizeof(a1[0]); 405 | // int t1[] = {0, 2, 3, 1, 3, 4}; 406 | // int t2[] = {0, 2, 1, 2, 2, 1}; 407 | // int e1 = 2, e2 = 4; 408 | // int l1 = 3, l2 = 2; 409 | // int fw = fastestWay(a1, a2, line_len, e1, e2, l1, l2, t1, t2); 410 | // cout< > dp(n + 1, vector(sa + 1, 0)); 424 | for(int k = 1; k <= n; ++k){ 425 | for(int i = 0; i <= sa; ++i){ 426 | if(i < ta[k - 1]){//不能放到A上去运行, ta[k - 1]表示第k个任务的运行时间 427 | dp[k][i] = dp[k - 1][i] + tb[k - 1]; 428 | }else{ 429 | dp[k][i] = min(dp[k - 1][i] + tb[k - 1], dp[k - 1][i - ta[k - 1]]); 430 | } 431 | } 432 | } 433 | int result = INT_MAX; 434 | for(int i = 0; i <= sa; ++i){ 435 | int tmp = max(dp[n][i], i); 436 | result = min(result, tmp); 437 | } 438 | return result; 439 | } 440 | 441 | //************************************************************ 442 | //http://chenjianneng3.blog.163.com/blog/static/128345126201110174316561/ 443 | //并行机调度, m台机器, n个任务,t为任务的执行时间 444 | bool cmp(const int &a, const int &b){ 445 | return a > b; 446 | } 447 | 448 | int parallel_schedule(int *t, int n, int m){ 449 | if(t == NULL) return 0; 450 | 451 | sort(t, t + n, cmp); 452 | int *c = new int[m](); 453 | //初始化m个机器执行任务的时间 454 | for(int i = 0; i < m; ++i){ 455 | c[i] = t[i]; 456 | } 457 | //对于剩下的任务,每次从机器中选择当前耗时最短的来执行 458 | for(int j = m; j < n; ++j){ 459 | sort(c, c + m, cmp); 460 | c[m - 1] += t[j]; 461 | } 462 | //选出最大的即是所求解 463 | sort(c, c + m, cmp); 464 | int result = c[0]; 465 | delete[] c; 466 | return result; 467 | } 468 | 469 | 470 | //************************************************************ 471 | void printMatrix(vector > &matrix){ 472 | for(int i = 0; i < matrix.size(); ++i){ 473 | for(int j = 0; j < matrix[i].size(); ++j){ 474 | cout< 2 | #include 3 | using namespace std; 4 | 5 | void findMost1(int *a, int n, int *ans){ 6 | assert( a != NULL && ans != NULL); 7 | int candidate[1] = { INT_MAX }; 8 | int cnt[1] = {0}; 9 | for(int i = 0; i < n; ++i){ 10 | if(a[i] == candidate[0]) cnt[0]++; 11 | else if(cnt[0] == 0) { candidate[0] = a[i]; cnt[0]++; } 12 | else{ 13 | cnt[0]--; 14 | } 15 | } 16 | ans[0] = candidate[0]; 17 | } 18 | 19 | void findMost2(int *a, int n, int *ans){ 20 | assert(a != NULL && ans != NULL); 21 | int candidates[2] = {INT_MAX, INT_MAX}; 22 | int cnt[2] = {0, 0}; 23 | for(int i = 0; i < n; ++i){ 24 | if(a[i] == candidates[0]) cnt[0]++; 25 | else if(a[i] == candidates[1]) cnt[1]++; 26 | else if(0 == cnt[0]) { candidates[0] = a[i]; cnt[0]++; } 27 | else if(0 == cnt[1]) { candidates[1] = a[i]; cnt[1]++; } 28 | else{ 29 | cnt[0]--, cnt[1]--; 30 | } 31 | } 32 | ans[0] = candidates[0]; 33 | ans[1] = candidates[1]; 34 | } 35 | 36 | bool findMost3(int *a, int n, int *ans){ 37 | int candidates[3] = {INT_MAX, INT_MAX, INT_MAX}; 38 | int cnt[3] = {0, 0, 0}; 39 | for(int i = 0; i < n; ++i){ 40 | if(a[i] == candidates[0]) cnt[0]++; 41 | else if(a[i] == candidates[1]) cnt[1]++; 42 | else if(a[i] == candidates[2]) cnt[2]++; 43 | else if(cnt[0] == 0) { candidates[0] = a[i]; cnt[0]++; } 44 | else if(cnt[1] == 0) { candidates[1] = a[i]; cnt[1]++; } 45 | else if(cnt[2] == 0) { candidates[2] = a[i]; cnt[2]++; } 46 | else{ 47 | cnt[0]--, cnt[1]--, cnt[2]--; 48 | } 49 | } 50 | ans[0] = candidates[0]; 51 | ans[1] = candidates[1]; 52 | ans[2] = candidates[2]; 53 | } 54 | 55 | int main() 56 | { 57 | int a[] = {1, 1, 1, 2, 2, 2, 4, 5, 5, 5}; 58 | int ans[3]; 59 | findMost3(a, 10, ans); 60 | cout< 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | const int VN = 4; 7 | 8 | class Graph{ 9 | public: 10 | Graph(); 11 | void addEdge(int start, int end, int weight); 12 | void bfs(); 13 | int bfs_path_length(int start, int end); 14 | void dfs(); 15 | void topoSort(); 16 | public: 17 | int edge[VN][VN]; 18 | int inDegree[VN]; 19 | }; 20 | 21 | Graph::Graph(){ 22 | for(int i = 0; i < VN; ++i){ 23 | for(int j = 0; j < VN; ++j){ 24 | edge[i][j] = INT_MAX; 25 | } 26 | } 27 | for(int i = 0; i < VN; ++i) 28 | inDegree[i] = 0; 29 | } 30 | 31 | void Graph::addEdge(int start, int end, int weight){ 32 | edge[start][end] = weight;//if unordered, we should add symmetric edge 33 | edge[end][start] = weight;//if unordered, we should add symmetric edge 34 | inDegree[end]++; 35 | } 36 | 37 | void Graph::bfs(){ 38 | bool *visited = new bool[VN]; 39 | for(int i = 0; i < VN; ++i) 40 | visited[i] = false; 41 | 42 | queue que; 43 | for(int i = 0; i < VN; ++i){ 44 | if(!visited[i]){ 45 | que.push(i); 46 | visited[i] = true; 47 | 48 | while(!que.empty()){ 49 | int c = que.front(); 50 | que.pop(); 51 | cout< que; 72 | que.push(start); 73 | int path = 0; 74 | while (!que.empty()) { 75 | int level_size = que.size(); 76 | for (int l = 0; l < level_size; ++l) { 77 | int p = que.front(); 78 | que.pop(); 79 | cout << "pop p = " << p << endl; 80 | if (p == end) { 81 | return path; 82 | } 83 | 84 | visited[p] = true; 85 | 86 | for (int j = 0; j < VN; ++j) { 87 | cout << "all j: " << j << endl; 88 | if (edge[p][j] != INT_MAX && !visited[j]) { 89 | cout << "conn, p = " << p << " j = " << j << endl; 90 | if (j == end) { 91 | return path + 1; 92 | } 93 | 94 | que.push(j); 95 | cout << "push j = " << j << endl; 96 | } 97 | } 98 | } 99 | 100 | path++; 101 | } 102 | 103 | delete[] visited; 104 | return -1; 105 | } 106 | 107 | void Graph::dfs(){ 108 | bool *visited = new bool[VN]; 109 | for(int i = 0; i < VN; ++i) 110 | visited[i] = false; 111 | 112 | stack stk; 113 | for(int i = 0; i < VN; ++i){ 114 | if(!visited[i]){ 115 | stk.push(i); 116 | while(!stk.empty()){ 117 | int c = stk.top(); 118 | stk.pop(); 119 | visited[c] = true; 120 | cout< que; 139 | for(int i = 0; i < VN; ++i){ 140 | if(!visited[i] && inDegree[i] == 0){ 141 | que.push(i); 142 | 143 | while(!que.empty()){ 144 | int c = que.front();//cur 145 | que.pop(); 146 | cout< 2 | using namespace std; 3 | 4 | class HashTable{ 5 | public: 6 | HashTable(int length); 7 | ~HashTable(); 8 | 9 | int hash(int key); 10 | bool insertLinear(int key); 11 | bool searchLinear(int key, int &addr); 12 | bool insertRand(int key); 13 | bool searchRand(int key, int &addr); 14 | private: 15 | int *m_elems; 16 | int m_len; 17 | }; 18 | 19 | HashTable::HashTable(int len){ 20 | m_len = len; 21 | m_elems = new int[len](); 22 | for(int i = 0; i < m_len; ++i){ 23 | m_elems[i] = INT_MAX; 24 | } 25 | } 26 | 27 | HashTable::~HashTable(){ 28 | m_len = 0; 29 | delete m_elems; 30 | } 31 | int HashTable::hash(int key){ 32 | return key % m_len; 33 | } 34 | 35 | bool HashTable::insertLinear(int key){ 36 | int addr = hash(key); 37 | while(m_elems[addr] != INT_MAX){ 38 | addr = (addr + 1) % m_len;//mod if for cycle 39 | if(addr == hash(key)) 40 | return false; 41 | } 42 | m_elems[addr] = key; 43 | return true; 44 | } 45 | 46 | bool HashTable::searchLinear(int key, int &addr){ 47 | addr = hash(key); 48 | while(m_elems[addr] != key){ 49 | addr = (addr + 1) % m_len; 50 | if(addr == hash(key) || m_elems[addr] == INT_MAX) 51 | return false; 52 | } 53 | return true; 54 | } 55 | 56 | bool HashTable::insertRand(int key){ 57 | int addr = hash(key); 58 | while(m_elems[addr] != INT_MAX){ 59 | addr = (addr + rand()) % m_len; 60 | } 61 | m_elems[addr] = key; 62 | return true; 63 | } 64 | 65 | bool HashTable::searchRand(int key, int &addr){ 66 | addr = hash(key); 67 | while(m_elems[addr] != key){ 68 | addr = (addr + rand()) % m_len; 69 | if(m_elems[addr] == INT_MAX || addr == hash(key)) 70 | return false; 71 | } 72 | return true; 73 | } 74 | 75 | int main(){ 76 | int a[12] = {12, 67, 56, 16, 25, 37, 22, 29, 15, 47, 48, 34}; 77 | HashTable map(50); 78 | for(int i = 0; i < 12; ++i){ 79 | map.insertRand(a[i]); 80 | } 81 | int addr; 82 | cout< 2 | using namespace std; 3 | 4 | struct ListNode{ 5 | int val; 6 | ListNode *next; 7 | ListNode(int x = 0) : val(x), next(NULL){} 8 | }; 9 | 10 | class HashTable{ 11 | public: 12 | HashTable(int len); 13 | ~HashTable(); 14 | 15 | int hash(int key); 16 | bool insert(int key); 17 | bool search(int key, int &addr); 18 | private: 19 | ListNode* (*m_elems); 20 | int m_len; 21 | }; 22 | 23 | HashTable::HashTable(int len){ 24 | m_len = len; 25 | m_elems = new ListNode*[m_len]; 26 | for(int i = 0; i < m_len; ++i){ 27 | m_elems[i] = new ListNode(); 28 | } 29 | } 30 | 31 | HashTable::~HashTable(){ 32 | for(int i = 0; i < m_len; ++i){ 33 | ListNode *h = m_elems[i]; 34 | while(h != NULL){ 35 | ListNode *t = h; 36 | h = h->next; 37 | delete t; 38 | } 39 | } 40 | } 41 | 42 | int HashTable::hash(int key){ 43 | return key % m_len; 44 | } 45 | 46 | bool HashTable::insert(int key){ 47 | int addr = hash(key); 48 | ListNode *newNode = new ListNode(key); 49 | newNode->next = m_elems[addr]->next; 50 | m_elems[addr]->next = newNode; 51 | return true; 52 | } 53 | 54 | bool HashTable::search(int key, int &addr){ 55 | addr = hash(key); 56 | ListNode *p = m_elems[addr]->next; 57 | while(p != NULL){ 58 | if(p->val == key) return true; 59 | p = p->next; 60 | } 61 | return false; 62 | } 63 | 64 | int main(){ 65 | int a[12] = {12, 67, 56, 16, 25, 37, 22, 29, 15, 47, 48, 34}; 66 | HashTable map(50); 67 | for(int i = 0; i < 12; ++i){ 68 | map.insert(a[i]); 69 | } 70 | int addr; 71 | cout< 2 | #include 3 | 4 | using namespace std; 5 | 6 | class MidFinder { 7 | public: 8 | void AddNum(int num) { 9 | // the size of max heap doesn't change, min heap size add one 10 | // cool codes! 11 | m_max_heap.push(num); 12 | m_min_heap.push(m_max_heap.top()); 13 | m_max_heap.pop(); 14 | 15 | if (m_min_heap.size() > m_max_heap.size()) { 16 | m_max_heap.push(m_min_heap.top()); 17 | m_min_heap.pop(); 18 | } 19 | } 20 | 21 | float FindMedian() { 22 | if (m_max_heap.size() == m_min_heap.size()) { 23 | return (m_max_heap.top() + m_min_heap.top()) / 2.0f; 24 | } else { 25 | // only one possibility, min heap size is one larger 26 | return m_min_heap.top(); 27 | } 28 | } 29 | 30 | private: 31 | priority_queue m_max_heap; 32 | priority_queue, greater > m_min_heap; 33 | }; 34 | 35 | int main() { 36 | MidFinder mf; 37 | mf.AddNum(2); 38 | mf.AddNum(3); 39 | cout << mf.FindMedian() << endl; 40 | mf.AddNum(4); 41 | cout << mf.FindMedian() << endl; 42 | return 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /HeapSort_Priority_queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | struct ListNode{ 6 | int val; 7 | ListNode(int x) : val(x){} 8 | }; 9 | 10 | struct cmp{ 11 | bool operator()(ListNode a, ListNode b){ 12 | return a.val > b.val; 13 | } 14 | }; 15 | 16 | int main(){ 17 | priority_queue, cmp> pq; 18 | for(int i = 0; i < 10; ++i){ 19 | ListNode tmp(rand() % 100); 20 | pq.push(tmp); 21 | } 22 | 23 | while(!pq.empty()){ 24 | ListNode t = pq.top(); 25 | pq.pop(); 26 | cout< 2 | using namespace std; 3 | 4 | //typedef int heap_elem_t; 5 | 6 | struct heap_t{ 7 | int size; 8 | int capacity; 9 | int *elems; 10 | }; 11 | 12 | heap_t* createHeap(const int capacity) 13 | { 14 | heap_t *h = (heap_t*) malloc(sizeof(heap_t)); 15 | h->size = 0; 16 | h->capacity = capacity; 17 | h->elems = (int*) malloc(capacity * sizeof(int)); 18 | return h; 19 | } 20 | 21 | void heapDestroy(heap_t *h) 22 | { 23 | free(h->elems); 24 | free(h); 25 | } 26 | 27 | //小根堆的自上往下的筛选算法, 通常在删除最大或者最小值得时候使用 28 | //h: 堆对象的指针, start: 开始的结点的索引 29 | void heap_sift_down(const heap_t *h, const int start) 30 | { 31 | int i = start, j; 32 | const int tmp = h->elems[start]; 33 | 34 | //j points to the left child of i 35 | for(j = 2 * i + 1; j < h->size; j = 2 * i + 1){ 36 | //get the smaller child, in order to switch it 37 | if(j < h->size - 1 && 38 | h->elems[j] > h->elems[j+1]) j = j + 1; 39 | 40 | if(tmp <= h->elems[j]) break; 41 | else{ 42 | //now elems[j] holds the minimum among the three elems 43 | h->elems[i] = h->elems[j]; //move the minimum one upstairs 44 | i = j; 45 | } 46 | }//end for 47 | 48 | h->elems[i] = tmp; // 考虑极限情况,直接退出循环,tmp必定是赋值给i号位置 49 | 50 | return; 51 | } 52 | 53 | //小根堆的自下往上筛选法,通常在插入新元素的时候使用 54 | void heap_sift_up(const heap_t *h, const int start) 55 | { 56 | int j = start, i = 0; // parent = (child - 1) / 2 57 | const int tmp = h->elems[start]; 58 | for (i = (j - 1) / 2; i >= 0; i = (j - 1) / 2) { 59 | if(h->elems[i] < tmp){ 60 | break; 61 | }else{ 62 | h->elems[j] = h->elems[i]; 63 | j = i; 64 | i = (j - 1) / 2; 65 | } 66 | } 67 | 68 | h->elems[j] = tmp; // 考虑极限情况,直接退出循环,tmp必定是赋值给j号位置 69 | } 70 | 71 | void heap_sort(int a[], const int n) 72 | { 73 | heap_t *h; 74 | h = createHeap(n); 75 | //we should delete the memory which is allocated in createHeap() 76 | int *old_memory = h->elems; 77 | h->elems = a; 78 | h->size = n; 79 | 80 | int i = (h->size - 2) / 2; // h->size - 1 is index, (h->size - 1 - 1) / 2 is its parent 81 | //自底向上逐步形成最小堆, 从第一个分支节点逆层序遍历,后面的比较每一次都是和3者中另外两个较小的那个比较 82 | while(i >= 0){ 83 | heap_sift_down(h, i); 84 | i--; 85 | } 86 | 87 | //依次取出堆顶 88 | for(i = h->size - 1; i > 0; --i){ 89 | swap(h->elems[0], h->elems[i]); 90 | h->size--; 91 | heap_sift_down(h, 0); 92 | } 93 | 94 | h->elems = old_memory; 95 | heapDestroy(h); 96 | } 97 | 98 | int main() 99 | { 100 | int a[] = {2, 0, 3, 4, 5, 6, 1, 9, 7, 8}; 101 | heap_sort(a, 10); 102 | for(int i = 0; i < 10; ++i) 103 | cout< 2 | using namespace std; 3 | 4 | struct heap_t{ 5 | int size; 6 | int capacity; 7 | int *elems; 8 | }; 9 | 10 | heap_t* createHeap(const int capacity) 11 | { 12 | heap_t *h = (heap_t*)malloc(sizeof(heap_t)); 13 | h->size = 0; 14 | h->capacity = capacity; 15 | h->elems = (int*) malloc(sizeof(int) * capacity); 16 | return h; 17 | } 18 | 19 | void heapDestroy(heap_t *h) 20 | { 21 | free(h->elems); 22 | free(h); 23 | } 24 | 25 | void heap_sift_down(const heap_t *h, const int start) 26 | { 27 | int i = start, j; 28 | const int tmp = h->elems[start]; 29 | 30 | for(j = 2*i+1; j < h->size; j = 2*i+1){ 31 | //get the bigger child 32 | //if j = h->size - 1, then no right child of node i, so skip the if 33 | if(j < h->size - 1 34 | && h->elems[j+1] > h->elems[j]) j = j + 1; 35 | 36 | if(tmp >= h->elems[j]){ 37 | break; 38 | }else{ 39 | //elems[j] is maximum, move upward 40 | h->elems[i] = h->elems[j]; 41 | i = j; 42 | } 43 | } 44 | h->elems[i] = tmp; 45 | } 46 | 47 | void heap_sift_up(const heap_t *h, const int start) 48 | { 49 | int j = start; 50 | int i = (j - 1) / 2; 51 | const int tmp = h->elems[start]; 52 | for(; i >= 0; i = (j - 1) / 2){ 53 | if(h->elems[i] > tmp){ 54 | break; 55 | }else{ 56 | h->elems[j] = h->elems[i]; 57 | j = i; 58 | } 59 | } 60 | h->elems[j] = tmp; 61 | } 62 | 63 | 64 | void heap_sort(int a[], const int n) 65 | { 66 | heap_t *h; 67 | h = createHeap(n); 68 | int *old_memory = h->elems; 69 | h->elems = a; 70 | h->size = n; 71 | 72 | //construct the heap 73 | int i = (h->size - 2) / 2; 74 | while(i >= 0){ 75 | heap_sift_down(h, i); 76 | --i; 77 | } 78 | 79 | //pop to sort 80 | for(i = h->size - 1; i > 0; --i){ 81 | swap(h->elems[i], h->elems[0]); 82 | h->size--; 83 | heap_sift_down(h, 0); 84 | } 85 | 86 | h->elems = old_memory; 87 | heapDestroy(h); 88 | } 89 | 90 | int main() 91 | { 92 | int a[] = {2, 0, 3, 4, 5, 6, 1, 9, 7, 8}; 93 | heap_sort(a, 10); 94 | for(int i = 0; i < 10; ++i) 95 | cout< 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | 13 | //************************************************************ 14 | //Union and Intersection of two sorted arrays 15 | //http://www.geeksforgeeks.org/union-and-intersection-of-two-sorted-arrays-2/ 16 | vector findUnion(int arr1[], int m, int arr2[], int n){ 17 | vector result; 18 | int i = 0, j = 0; 19 | while(i < m && j < n){ 20 | if(arr1[i] < arr2[j]) result.push_back(arr1[i++]); 21 | else if(arr1[i] > arr2[j]) result.push_back(arr2[j++]); 22 | else{ 23 | result.push_back(arr1[i]); 24 | i++, j++; 25 | } 26 | } 27 | 28 | while(i < m) result.push_back(arr1[i++]); 29 | while(j < n) result.push_back(arr2[j++]); 30 | return result; 31 | } 32 | 33 | vector findIntersection(int arr1[], int m, int arr2[], int n){ 34 | vector result; 35 | int i = 0, j = 0; 36 | while(i < m && j < n){ 37 | if(arr1[i] < arr2[j]) i++; 38 | else if(arr1[i] > arr2[j]) j++; 39 | else{ 40 | result.push_back(arr1[i]); 41 | i++, j++; 42 | } 43 | } 44 | return result; 45 | } 46 | 47 | //Union and Intersection of three sorted arrays 48 | //http://www.geeksforgeeks.org/union-and-intersection-of-two-sorted-arrays-2/ 49 | set findUnion3(int arr1[], int n1, int arr2[], int n2, int arr3[], int n3){ 50 | set result; 51 | for(int i = 0; i < n1; ++i) result.insert(arr1[i]); 52 | for(int i = 0; i < n2; ++i) result.insert(arr2[i]); 53 | for(int i = 0; i < n3; ++i) result.insert(arr3[i]); 54 | return result; 55 | } 56 | 57 | vector findIntersection3(int arr1[], int n1, int arr2[], int n2, int arr3[], int n3){ 58 | vector result; 59 | int i = 0, j = 0, k = 0; 60 | while(i < n1 && j < n2 && k < n3){ 61 | if(arr1[i] == arr2[j] && arr2[j] == arr3[k]) { 62 | result.push_back(arr1[i]); 63 | i++, j++, k++; 64 | }else if(arr1[i] < arr2[j]){ 65 | i++; 66 | }else if(arr2[j] < arr3[k]){ 67 | j++; 68 | }else{ 69 | k++; 70 | } 71 | } 72 | return result; 73 | } 74 | 75 | //************************************************************ 76 | bool isPrim(int n){ 77 | if(n <= 1) return false; 78 | 79 | for(int i = 2; i * i <= n; ++i){ 80 | if(n % i == 0) return false; 81 | } 82 | return true; 83 | } 84 | 85 | //************************************************************ 86 | //筛数法,求N以内的所有素数, n > 2; 87 | vector getAllPrim(int n){ 88 | vector res; 89 | 90 | vector isPrime(n + 1, false); 91 | for(int i = 2; i * i <= n; ++i){ 92 | for(int j = 1; j * i <= n; ++j){ 93 | if(isPrime[j * i] && (n % (j * i) == 0)) 94 | isPrime[j * i] = true; 95 | }//end for j 96 | }//end for i 97 | 98 | } 99 | 100 | //************************************************************ 101 | //分解质因数,1既不是质数也不是合数 102 | void prim(int n){ 103 | for(int i = 2; i <= n; ++i){ 104 | while(n % i == 0){ 105 | cout< m){ 113 | while(n % m != 0) m++; 114 | cout< suffix; 129 | int n = str.length(); 130 | for(int i = 0; i < n; ++i){ 131 | suffix.push_back(str.substr(i)); 132 | } 133 | sort(suffix.begin(), suffix.end()); 134 | int max_len = 0; 135 | string max_str; 136 | for(int i = 1; i < suffix.size(); ++i){ 137 | int p = 0, len = 0; 138 | while(p < suffix[i - 1].length() && p < suffix[i].length()){ 139 | if(suffix[i - 1][p] != suffix[i][p]) break; 140 | p++, len++; 141 | } 142 | if(len > max_len){ 143 | max_len = len; 144 | max_str = suffix[i].substr(0, max_len); 145 | } 146 | } 147 | return max_str; 148 | } 149 | 150 | //波兰表达式:前缀表达式;逆波兰表达式:后缀表达式 151 | 152 | /*1.中缀表达式求值,先中缀转后缀,基于后缀表达式计算值 153 | 使用两个栈,操作符栈,操作数栈,从左往右扫描表达式,遇到操作数直接压入操作数栈,遇到操作符,跟操作符栈栈顶元素比较优先级,当且仅当当前操作符比栈顶小的时候,直接压栈(如果大于或者等于栈顶元素,则弹出栈顶元素,将其压入操作数栈,类似保持金字塔形式),优先级(乘除 > 加减 > 等号),等号优先级最低 */ 154 | 155 | /*2.将一个 逆波兰式(后缀表达式) 转回 中缀表达式 的算法: 156 | 这个就相当简单了,就是一个机械的入堆栈出堆栈的操作, 157 | 1)设置一个堆栈,将逆波兰式从左到右开始进行出入堆栈操作,还以上例为例:1,2,3,+,* 158 | 2)遇到数字直接压栈;例如,上例逆波兰先进行三次入栈操作,堆栈的格局是: 1,2,3(栈顶); 159 | 3)遇到算符,将堆栈中的两个数字出栈。 如,读到+号后,2,3出栈,进行运算。注意,出栈时先出栈的元素是右算子,后出栈的是左算子,上例是2+3,不是3+2; 160 | 4)将运算的结果作为新的算子,压入堆栈中。如运算结果(2+3)入栈,堆栈格局:1,(2+3); 161 | 5)反复1-4的操作,得到的中序表达式就是: 1*(2+3); 162 | */ 163 | /*给中缀表达式,1+2*(3-4)+5,建树。 164 | 表达式树特点,操作数必定在叶节点,操作符必定在内部节点。 165 | 过程:选最后一个计算的符号,放在根节点,该运算符的左半部分放在左子树,有半部分放在由子树,递归直至结束 166 | */ 167 | 168 | vector inToPost(vector &expression){ 169 | vector post; 170 | if(expression.empty()) return post; 171 | 172 | map cache; 173 | cache['+'] = 0; 174 | cache['-'] = 0; 175 | cache['*'] = 1; 176 | cache['/'] = 1; 177 | 178 | stack oper; 179 | stack opnd; 180 | for(int i = 0; i < (int)expression.size(); ++i){ 181 | string tmp = expression[i]; 182 | if(tmp.size() == 1 && tmp[0] == '+' && tmp[0] == '-' 183 | && tmp[0] == '*' && tmp[0] == '/'){ 184 | while(!oper.empty()){ 185 | if(cache[tmp[0]] < cache[oper.top()]) 186 | break; 187 | 188 | string op; 189 | op[0] = tmp[0];//char to string 190 | post.push_back(op); 191 | oper.pop(); 192 | } 193 | oper.push(tmp[0]); 194 | }else{ 195 | post.push_back(expression[i]); 196 | } 197 | }//end for 198 | return post; 199 | } 200 | 201 | //************************************************************ 202 | //正负交替 203 | // 给定一个包含正负数的数组,按照正负交替的方式重新排列元素,但是正数或负数内部各自元素的相对位置不变,要求 204 | // 空间复杂度O(1), 比如 205 | // 输入: arr[] = {1, 2, 3, -4, -1, 4} 206 | // 输出:arr[] = {-4, 1, -1, 2, 3, 4} 207 | // 输入:arr[] = {-5, -2, 5, 2, 4, 7, 1, 8, 0, -8} 208 | // 输出:arr[] = {-5, 5, -2, 2, -8, 4, 7, 1, 8, 0} 209 | void rearrange(int *a, int n){ 210 | 211 | } 212 | 213 | //************************************************************ 214 | //实现引用计数类,见隔壁的文件ReferenceCount.cpp 215 | 216 | 217 | //************************************************************ 218 | //题目是这样的,两个长度相等的字符串,每个字符串中删掉一个字符,剩下的字符顺序不变,如果这样操作后得到的两个结果相同,就说是原来的两个字符串是相似的,实现函数 219 | //O(n^2) 220 | bool isSimilar(char str1[], char str2[], int length){ 221 | if(str1 == NULL && str2 == NULL) return true; 222 | else if(str1 == NULL || str2 == NULL) return false; 223 | 224 | string s1(str1); 225 | string s2(str2); 226 | for(int i = 0; i < length; ++i){ 227 | string tmp1 = s1; 228 | tmp1.erase(i, 1); 229 | for(int j = 0; j < length; ++j){ 230 | string tmp2 = s2; 231 | tmp2.erase(j, 1); 232 | if(tmp1 == tmp2) return true; 233 | } 234 | } 235 | return false; 236 | } 237 | 238 | //O(n) 239 | bool isSimilar2(char str1[], char str2[], int length){ 240 | if(str1 == NULL && str2 == NULL) return true; 241 | else if(str1 == NULL || str2 == NULL) return false; 242 | 243 | int p1 = 0, p2 = length - 1; 244 | while(p1 < p2 && str1[p1] == str2[p1]) p1++; 245 | while(p1 < p2 && str1[p2] == str2[p2]) p2--; 246 | 247 | string s1(str1), s2(str2); 248 | string tmp1 = s1, tmp2 = s2; 249 | if(tmp1.erase(p1, 1) == tmp2.erase(p1, 1)) return true; 250 | tmp1 = s1, tmp2 = s2; 251 | if(tmp1.erase(p1, 1) == tmp2.erase(p2, 1)) return true; 252 | tmp1 = s1, tmp2 = s2; 253 | if(tmp1.erase(p2, 1) == tmp2.erase(p1, 1)) return true; 254 | tmp1 = s1, tmp2 = s2; 255 | if(tmp1.erase(p2, 1) == tmp2.erase(p2, 1)) return true; 256 | return false; 257 | } 258 | 259 | //************************************************************ 260 | //一个整数数组,长度为n,每个数的范围都是1~n+1,每个数字不重复,乱序的,求缺失的一个数 261 | int findOneMissing(int *a, int n){ 262 | if(a == NULL) return INT_MAX; 263 | unordered_map cache; 264 | for(int i = 0; i < n; ++i){ 265 | cache[a[i]] = true; 266 | } 267 | 268 | for(int i = 1; i <= n + 1; ++i){ 269 | if(cache.find(i) == cache.end()){ 270 | return i; 271 | } 272 | } 273 | return INT_MAX; 274 | } 275 | 276 | //一个整数数组,长度为n,每个数的范围都是1~n+2,每个数字不重复,乱序的,求缺失的两个数 277 | vector findTwoMissing(int *a, int n){ 278 | vector result; 279 | if(a == NULL) return result; 280 | 281 | unordered_map cache; 282 | for(int i = 0; i < n; ++i){ 283 | cache[a[i]] = true; 284 | } 285 | 286 | for(int i = 1; i <= n + 2; ++i){ 287 | if(cache.find(i) == cache.end()){ 288 | result.push_back(i); 289 | } 290 | } 291 | return result; 292 | } 293 | //以上类型的问题,可以通过 不同的方式 构造方程,然后解方程。缺失两个数,就构造两个方程,3个数就构造三个方程(和,积, 平方和,立方和等等) 294 | 295 | //************************************************************ 296 | //comes from programming pearls 297 | void randomShuffle(int a[], int n){ 298 | if(a == NULL) return; 299 | 300 | for(int i = 0; i < n; ++i){ 301 | int tmp = rand() % (n - i); 302 | swap(a[tmp], a[n - 1 - i]); 303 | } 304 | } 305 | 306 | //************************************************************ 307 | //蓄水池抽样 308 | //http://handspeaker.iteye.com/blog/1167092 309 | //1 ------k--------i--------N, N 趋近无穷大, 以k/i的概率选择第i个 310 | vector reservoirSampling(int k){ 311 | vector result; 312 | //end with -1; 313 | int i = 0, val; 314 | while(result.size() < k){ 315 | cin>>val; 316 | result.push_back(val); 317 | i++;//i-th number 318 | } 319 | 320 | //core part 321 | while(cin>>val){ 322 | if(val == -1) 323 | return result; 324 | i++; 325 | int m = rand() % i; 326 | if(m < k){ 327 | result[m] = val; 328 | } 329 | } 330 | return result; 331 | } 332 | 333 | //************************************************************ 334 | //求一个序列的第k个排列 335 | vector kth_permutation(vector &num, int k){ 336 | if(num.empty()) return num; 337 | 338 | for(int i = 0; i < k; ++i){ 339 | next_permutation(num.begin(), num.end()); 340 | } 341 | return num; 342 | } 343 | 344 | //************************************************************ 345 | //求整数得二进制表示中1的个数 346 | int func(unsigned int i){ 347 | unsigned int temp = i; 348 | temp = (temp & 0x55555555) + ((temp & 0xaaaaaaaa) >> 1); 349 | temp = (temp & 0x33333333) + ((temp & 0xcccccccc) >> 2); 350 | temp = (temp & 0x0f0f0f0f) + ((temp & 0xf0f0f0f0) >> 4); 351 | temp = (temp & 0x00ff00ff) + ((temp & 0xff00ff00) >> 8); 352 | temp = (temp & 0x0000ffff) + ((temp & 0xffff0000) >> 16); 353 | return temp; 354 | } 355 | 356 | //************************************************************ 357 | //hanoi recursive solutions 358 | void hanoi(int n, char a, char b, char c){ 359 | if(n == 1){ 360 | cout<<"from " << a <<" to " < &array){ 457 | for(auto it = array.begin(); it != array.end(); ++it){ 458 | cout<<*it<<" "; 459 | } 460 | cout< res_union = findUnion3(ar1, n1, ar2, n2, ar3, n3); 473 | printSet(res_union); 474 | return 0; 475 | } 476 | -------------------------------------------------------------------------------- /LinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct ListNode{ 5 | int val; 6 | ListNode *next; 7 | ListNode(int x) : val(x), next(NULL){} 8 | }; 9 | 10 | ListNode* createList(int n){ 11 | ListNode dummy(-1); 12 | ListNode *p = &dummy; 13 | for(int i = 0; i < n; ++i){ 14 | ListNode *t = new ListNode(i); 15 | p->next = t; 16 | p = p->next; 17 | } 18 | return dummy.next; 19 | } 20 | 21 | //************************************************************ 22 | ListNode* insertAtHead(ListNode *head, int val){ 23 | ListNode *newNode = new ListNode(val); 24 | newNode->next = head; 25 | return newNode; 26 | } 27 | 28 | ListNode* insertAtTail(ListNode *head, int val){ 29 | ListNode dummy(-1); 30 | dummy.next = head; 31 | 32 | ListNode *p = &dummy; 33 | while(p->next != NULL){ 34 | p = p->next; 35 | } 36 | ListNode *newNode = new ListNode(val); 37 | p->next = newNode; 38 | return dummy.next; 39 | } 40 | //************************************************************ 41 | ListNode* reverse(ListNode *head){ 42 | ListNode *pre = NULL, *cur = head, *nxt = NULL; 43 | while(cur != NULL){ 44 | nxt = cur->next; 45 | cur->next = pre; 46 | pre = cur; 47 | cur = nxt; 48 | } 49 | return pre; 50 | } 51 | 52 | ListNode* reverse_recur(ListNode *head, ListNode *&new_head) { 53 | if (head == NULL) { 54 | return NULL; 55 | } 56 | 57 | //head keep moving ahead, and arrive at the end node 58 | if (head->next == NULL) { 59 | //end of the old list is the new head 60 | new_head = head; 61 | return head; 62 | } 63 | 64 | ListNode *new_tail = reverse_recur(head->next, new_head); 65 | new_tail->next = head; 66 | head->next = NULL; 67 | return head; // this is used as new_tail for the prev function call 68 | } 69 | 70 | //************************************************************ 71 | //O(1) 72 | bool delNode(ListNode *&head, ListNode *del){ 73 | if(head == NULL || del == NULL) { 74 | return false; 75 | } 76 | 77 | if(del->next != NULL) { 78 | del->val = del->next->val; 79 | ListNode *tmp = del->next; 80 | del->next = del->next->next; 81 | delete tmp; 82 | return true; 83 | } else {// the last node 84 | ListNode dummy(-1); 85 | dummy.next = head; 86 | ListNode *prev = &dummy; 87 | while(prev != NULL && prev->next != del) { 88 | prev = prev->next; 89 | } 90 | 91 | if(prev == NULL) { 92 | return false; 93 | } 94 | 95 | prev->next = del->next; 96 | delete del; 97 | // must, if del is the head, and there's only one element 98 | head = dummy.next; 99 | return true; 100 | } 101 | } 102 | 103 | //************************************************************ 104 | ListNode* kthNode(ListNode *head, int k){ 105 | if(head == NULL) return NULL; 106 | while(--k > 0 && head != NULL) 107 | head = head->next; 108 | return head; 109 | } 110 | 111 | //************************************************************ 112 | ListNode* findMid(ListNode *head){ 113 | if(head == NULL || head->next == NULL) return head; 114 | 115 | ListNode *slow = head, *fast = head; 116 | while(fast != NULL && fast->next != NULL){ 117 | fast = fast->next->next; 118 | slow = slow->next; 119 | } 120 | return slow; 121 | } 122 | 123 | //************************************************************ 124 | ListNode* mergeTwoSortedList(ListNode *h1, ListNode *h2){ 125 | ListNode dummy(-1); 126 | ListNode *p = &dummy; 127 | while(h1 != NULL && h2 != NULL){ 128 | if(h1->val < h2->val){ 129 | p->next = h1; 130 | h1 = h1->next; 131 | }else{ 132 | p->next = h2; 133 | h2 = h2->next; 134 | } 135 | p = p->next; 136 | } 137 | if(h1 != NULL) p->next = h1; 138 | if(h2 != NULL) p->next = h2; 139 | return dummy.next; 140 | } 141 | 142 | //************************************************************ 143 | ListNode* merge(ListNode *h1, ListNode *h2){ 144 | ListNode dummy(-1); 145 | ListNode *p = &dummy; 146 | while(h1 != NULL && h2 != NULL){ 147 | if(h1->val < h2->val){ 148 | p->next = h1; 149 | h1 = h1->next; 150 | }else{ 151 | p->next = h2; 152 | h2 = h2->next; 153 | } 154 | p = p->next; 155 | } 156 | if(h1 != NULL) p->next = h1; 157 | if(h2 != NULL) p->next = h2; 158 | return dummy.next; 159 | } 160 | 161 | ListNode* sortList(ListNode* head){ 162 | if(head == NULL || head->next == NULL){ 163 | return head; 164 | } 165 | 166 | ListNode *slow = head, *fast = head->next; 167 | while(fast != NULL && fast->next != NULL){ 168 | fast = fast->next->next; 169 | slow = slow->next; 170 | } 171 | ListNode *mid = slow; 172 | 173 | ListNode *h1 = head, *h2 = mid->next; 174 | mid->next = NULL; 175 | h1 = sortList(h1); 176 | h2 = sortList(h2); 177 | return merge(h1, h2); 178 | } 179 | 180 | //************************************************************ 181 | bool hasCycle(ListNode *head){ 182 | if(head == NULL) return false; 183 | 184 | ListNode *slow = head, *fast = head; 185 | do{ 186 | if(fast == NULL || fast->next == NULL) 187 | return false; 188 | fast = fast->next->next; 189 | slow = slow->next; 190 | }while(fast != slow); 191 | return true; 192 | } 193 | 194 | ListNode* detectCycle(ListNode *head){ 195 | if(head == NULL) return NULL; 196 | 197 | ListNode *slow = head, *fast = head; 198 | do{ 199 | if(fast == NULL || fast->next == NULL) 200 | return NULL; 201 | fast = fast->next->next; 202 | slow = slow->next; 203 | }while(fast != slow); 204 | 205 | fast = head; 206 | while(fast != slow){ 207 | fast = fast->next; 208 | slow = slow->next; 209 | } 210 | return fast; 211 | } 212 | //test program: 213 | // ListNode *h1 = createList(10); 214 | // ListNode *tail = h1; 215 | // while(tail != NULL && tail->next != NULL){ 216 | // tail = tail->next; 217 | // } 218 | // ListNode *kth = kthNode(h1, 3); 219 | // tail->next = kth; 220 | // ListNode *enter = detectCycle(h1); 221 | // cout<val <next; 234 | cnt++; 235 | if(cnt > k){ 236 | slow = slow->next; 237 | } 238 | } 239 | if(cnt < k) return NULL; 240 | else return slow; 241 | } 242 | 243 | //************************************************************ 244 | void printList(ListNode *head){ 245 | while(head != NULL){ 246 | cout<val <<" "; 247 | head = head->next; 248 | } 249 | cout<val << endl; 268 | } 269 | 270 | return 0; 271 | } 272 | -------------------------------------------------------------------------------- /LinkedListUsingArray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct Node{ 5 | int val; 6 | int next; 7 | }; 8 | 9 | class ArrayLinkedList{ 10 | public: 11 | ArrayLinkedList(int cap){ 12 | if(cap == 0) return; 13 | 14 | m_capacity = cap; 15 | m_elems = new Node[m_capacity](); 16 | m_head = cap; 17 | m_available = 0; 18 | m_length = 0; 19 | 20 | for(int i = 0; i < m_capacity - 1; ++i){ 21 | m_elems[i].next = i + 1; 22 | } 23 | m_elems[m_capacity - 1].next = INT_MAX;//最后一个元素的next为INT_MAX; 24 | } 25 | 26 | ~ArrayLinkedList(){ 27 | delete[] m_elems; 28 | } 29 | 30 | //insert a element before the element at pos; 31 | void insertValAt(int pos, int val){ 32 | if(pos >= m_length) return; 33 | 34 | //available 管理可用空间 35 | int cur_avail = m_available; 36 | m_elems[m_available].val = val; 37 | m_available = m_elems[m_available].next; 38 | 39 | //管理已使用空间 40 | int prev = m_head; 41 | if(pos == 0){ 42 | m_elems[cur_avail].next = prev; 43 | m_head = cur_avail; 44 | m_length++; 45 | return; 46 | }else{ 47 | int t = m_head; 48 | while(--pos){ 49 | t = m_elems[t].next; 50 | } 51 | //add a element at the available pos; 52 | m_elems[cur_avail].next = t; 53 | m_elems[t].next = cur_avail; 54 | } 55 | } 56 | 57 | void delAt(int pos){ 58 | if(pos >= m_length) return; 59 | 60 | int cur_del; 61 | if(pos == 0){ 62 | cur_del = m_head; 63 | m_head = m_elems[m_head].next; 64 | m_length--; 65 | m_elems[cur_del].next = m_available; 66 | m_available = cur_del; 67 | }else{ 68 | int prev_to_del = m_head; 69 | while(--pos){ 70 | prev_to_del = m_elems[prev_to_del].next; 71 | } 72 | //把to_del加到可用空间中去 73 | int to_del = m_elems[prev_to_del].next; 74 | m_elems[to_del].next = m_available; 75 | m_available = to_del; 76 | //删除结点 77 | m_elems[prev_to_del].next = m_elems[to_del].next; 78 | } 79 | } 80 | 81 | 82 | private: 83 | int m_capacity; 84 | Node *m_elems; 85 | int m_available; 86 | int m_head; 87 | int m_length; 88 | }; 89 | 90 | 91 | 92 | int main() 93 | { 94 | //代码未测试,不一定准确,Pay attention,仅提供一个思路 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /QueueUsingStack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class QueueUsingStack{ 6 | public: 7 | void push(int key); 8 | int front(); 9 | void pop(); 10 | bool empty(); 11 | 12 | private: 13 | stack in_stk; 14 | stack out_stk; 15 | }; 16 | 17 | void QueueUsingStack::push(int key){ 18 | in_stk.push(key); 19 | } 20 | 21 | void QueueUsingStack::pop(){ 22 | if(!out_stk.empty()){ 23 | out_stk.pop(); 24 | }else{ 25 | while(!in_stk.empty()){ 26 | out_stk.push(in_stk.top()); 27 | in_stk.pop(); 28 | } 29 | if(!out_stk.empty()){ 30 | out_stk.pop(); 31 | } 32 | } 33 | } 34 | 35 | int QueueUsingStack::front(){ 36 | if(!out_stk.empty()){ 37 | return out_stk.top(); 38 | }else{ 39 | while(!in_stk.empty()){ 40 | out_stk.push(in_stk.top()); 41 | in_stk.pop(); 42 | } 43 | 44 | if(!out_stk.empty()){ 45 | return out_stk.top(); 46 | }else{ 47 | return INT_MAX; 48 | } 49 | } 50 | } 51 | 52 | bool QueueUsingStack::empty(){ 53 | return in_stk.empty() && out_stk.empty(); 54 | } 55 | 56 | int main() 57 | { 58 | QueueUsingStack qus; 59 | for(int i = 0; i < 10; ++i){ 60 | qus.push(i); 61 | } 62 | while(!qus.empty()){ 63 | cout< 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | const bool RED = true; 8 | const bool BLACK = false; 9 | 10 | struct TreeNode{ 11 | int val; 12 | TreeNode *lchild, *rchild; 13 | bool color;//red: 1, black: 0 14 | int N; 15 | TreeNode(int x, bool c, int s) : val(x), lchild(NULL), rchild(NULL), color(c), N(s){} 16 | }; 17 | 18 | //************************************************************ 19 | //basic operations 20 | bool isRed(TreeNode *root){ 21 | if(root == NULL) return false; 22 | else return root->color == RED; 23 | } 24 | 25 | int size(TreeNode *root){ 26 | if(root == NULL) return 0; 27 | else return root->N; 28 | } 29 | 30 | TreeNode* rotateLeft(TreeNode *root){ 31 | assert(root != NULL && isRed(root->rchild)); 32 | //link 33 | TreeNode *rc = root->rchild; 34 | root->rchild = rc->lchild; 35 | rc->lchild = root; 36 | //color 37 | rc->color = root->color; 38 | root->color = RED; 39 | //size 40 | rc->N = root->N; 41 | root->N = size(root->lchild) + size(root->rchild) + 1; 42 | return rc; 43 | } 44 | 45 | TreeNode* rotateRight(TreeNode *root){ 46 | assert(root != NULL && isRed(root->lchild)); 47 | //link 48 | TreeNode *lc = root->lchild; 49 | root->lchild = lc->rchild; 50 | lc->rchild = root; 51 | //color 52 | lc->color = root->color; 53 | root->color = RED; 54 | //size 55 | lc->N = root->N; 56 | root->N = size(root->lchild) + size(root->rchild) + 1; 57 | return lc; 58 | } 59 | 60 | void flipColors(TreeNode *root){ 61 | assert(root != NULL && root->lchild != NULL && root->rchild != NULL); 62 | // h must have opposite color of its two children 63 | assert ((isRed(root) && !isRed(root->lchild) && !isRed(root->rchild)) 64 | || (!isRed(root) && isRed(root->lchild) && isRed(root->rchild)) ); 65 | 66 | root->color = !root->color; 67 | root->lchild->color = !root->lchild->color; 68 | root->rchild->color = !root->rchild->color; 69 | } 70 | 71 | //************************************************************ 72 | void insert(TreeNode *&root, TreeNode *newNode){ 73 | if(root == NULL) 74 | root = newNode; 75 | 76 | if(newNode->val < root->val){ 77 | insert(root->lchild, newNode); 78 | }else if(newNode->val > root->val){ 79 | insert(root->rchild, newNode); 80 | }else{ 81 | root->val = newNode->val;//overwrite the value 82 | } 83 | 84 | if(isRed(root->rchild) && !isRed(root->lchild)) root = rotateLeft(root); 85 | if(isRed(root->lchild) && root->lchild != NULL && isRed(root->lchild->lchild)) root = rotateRight(root); 86 | if(isRed(root->lchild) && isRed(root->rchild)) flipColors(root); 87 | root->N = size(root->lchild) + size(root->rchild) + 1; 88 | } 89 | 90 | 91 | TreeNode* createRBTree(int n){ 92 | TreeNode *root = NULL; 93 | for(int i = 0; i < n; ++i){ 94 | TreeNode *newNode = new TreeNode(i, RED, 1); 95 | insert(root, newNode); 96 | root->color = BLACK;//every time insert, label the root as BLACK 97 | } 98 | return root; 99 | } 100 | 101 | //************************************************************ 102 | bool search(TreeNode *root, int target){ 103 | while(root != NULL){ 104 | if(target == root->val){ 105 | return true; 106 | }else if(target > root->val){ 107 | return search(root->rchild, target); 108 | }else { 109 | return search(root->lchild, target); 110 | } 111 | } 112 | return false; 113 | } 114 | 115 | //************************************************************ 116 | //rank k means: in inorder traversal, there are k nodes smaller than it; 117 | TreeNode* selectRank(TreeNode *root, int k){ 118 | assert(root != NULL && k >= 0); 119 | 120 | int t = size(root->lchild); 121 | if(k > t) return selectRank(root->rchild, k - t - 1); 122 | else if(k < t) return selectRank(root->lchild, k); 123 | else return root; 124 | } 125 | 126 | //************************************************************ 127 | //assume no duplicates, return the rank of the target value 128 | int getRank(TreeNode *root, int target){ 129 | if(root == NULL) return 0; 130 | 131 | if(target > root->val){ 132 | return size(root->lchild) + 1 + getRank(root->rchild, target); 133 | }else if(target < root->val){ 134 | return getRank(root->lchild, target); 135 | }else{ 136 | return size(root->lchild); 137 | } 138 | } 139 | 140 | //************************************************************ 141 | void preOrder(TreeNode *root){ 142 | if(root == NULL) return ; 143 | stack stk; 144 | TreeNode *p = root; 145 | stk.push(p);//no need for inOrder and postOrder 146 | while(!stk.empty()){ 147 | p = stk.top(); 148 | stk.pop(); 149 | cout<val<<" "<<"size: " << p->N<rchild != NULL) stk.push(p->rchild); 152 | if(p->lchild != NULL) stk.push(p->lchild); 153 | } 154 | } 155 | 156 | int main() 157 | { 158 | TreeNode *root = createRBTree(5); 159 | preOrder(root); 160 | int n; 161 | while(cin>>n){ 162 | cout< 2 | using namespace std; 3 | 4 | //more effective c++, p158 5 | //first,这个只是一个引用计数类智能指针的模板,T需要从引用计数类继承而来 6 | template 7 | class RCPtr{ 8 | public: 9 | RCPtr(T *realPtr = NULL) : pointee(realPtr){ init(); } 10 | RCPtr(const RCPtr &rhs) : pointee(rhs.pointee){ init(); } 11 | RCPtr& operator=(const RCPtr &rhs){ 12 | if(pointee != rhs.pointee){ 13 | T *old = pointee; 14 | pointee = rhs.pointee; 15 | init(); 16 | if(old != NULL) old->removeReference(); 17 | } 18 | return *this; 19 | } 20 | ~RCPtr(){ if(pointee != NULL) pointee->removeReference(); } 21 | 22 | T* operator->() const{ return pointee; } 23 | T& operator*() const { return *pointee; } 24 | 25 | private: 26 | T *pointee;//raw pointer 27 | void init(){ 28 | if(pointee != NULL){ 29 | if(!pointee->isShareable()){ pointee = new T(*pointee); } 30 | else{ pointee->addReference(); } 31 | } 32 | } 33 | }; 34 | 35 | //second 36 | //引用计数对象,管理引用数目 37 | class RCObject{ 38 | public: 39 | RCObject() : refCount(0), shareable(true){ } 40 | RCObject(const RCObject& rhs) : refCount(0), shareable(true){ } 41 | RCObject& operator=(const RCObject &rhs){ return *this; } 42 | virtual ~RCObject() = 0;//!!pure virtual, no instantiation 43 | 44 | //common operations 45 | void addReference(){ ++refCount; } 46 | void removeReference(){ if(--refCount) delete this; }//销毁指针 47 | void markUnshareable(){ shareable = false; } 48 | bool isShareable() const{ return shareable; } 49 | bool isShared() const{ return refCount > 1; } 50 | private: 51 | size_t refCount; 52 | bool shareable; 53 | }; 54 | 55 | //third 56 | class String{ 57 | public: 58 | String(const char *initValue = "") : value(new StringValue(initValue)){ } 59 | const char& operator[](int index) const { return value->data[index]; } 60 | char& operator[](int index) { 61 | if(value->isShared()){ 62 | value = new StringValue(value->data); 63 | } 64 | value->markUnshareable(); 65 | return value->data[index]; 66 | } 67 | 68 | private: 69 | //保存引用计数和值的对应 70 | struct StringValue : public RCObject{ 71 | char *data;//数据域 72 | StringValue(const char *initValue){ init(initValue); } 73 | StringValue(const StringValue &rhs){ init(rhs.data); } 74 | ~StringValue(){ delete[] data; } 75 | void init(const char *initValue){ 76 | data = new char[strlen(initValue) + 1]; 77 | strcpy(data, initValue); 78 | } 79 | }; 80 | RCPtr value; 81 | }; 82 | 83 | //首先引用计数不应该在类中,因为每个string的值对应一个引用计数,而不是每个string对象。 84 | //本质上而言,两个大块,第一块就是 RCPtr这个智能指针的模板类,T类型要求是RCObject的子类, StringValue类本质上就是含有RCObject这个subobject的类型。 85 | //只是将引用计数操作交给父类去做了,自己只用管理data相关的事务, 86 | 87 | int main(){ 88 | return 0; 89 | } 90 | -------------------------------------------------------------------------------- /Search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int binary_search(int *a, int start, int end, int target){ 5 | if(a == NULL) return -1; 6 | int l = start, r = end; 7 | while(l < r){ 8 | const int mid = l + ((r - l) >> 1); 9 | if(a[mid] > target){ 10 | r = mid; 11 | }else if(a[mid] < target){ 12 | l = mid + 1; 13 | }else{ 14 | return mid; 15 | } 16 | } 17 | return -1; 18 | } 19 | 20 | int binary_search_recursive(int *a, int start, int end, int target) { 21 | if(a == NULL) { 22 | return -1; 23 | } 24 | 25 | if (start >= end) { 26 | return -1; 27 | } 28 | 29 | int mid = start + (end - start) / 2; 30 | if (a[mid] > target) { 31 | return binary_search_recursive(a, start, mid, target); 32 | } else if (a[mid] < target) { 33 | return binary_search_recursive(a, mid + 1, end, target); 34 | } else { 35 | return mid; 36 | } 37 | } 38 | 39 | //************************************************************ 40 | int binary_search_rotated(int *a, int start, int end, int target){ 41 | if(a == NULL) return -1; 42 | 43 | int l = start, r = end; 44 | while(l < r){ 45 | int m = l + ((r - l) >> 1); 46 | if(a[m] == target) return m; 47 | 48 | if(a[m] >= a[l]){ 49 | if(target >= a[l] && target <= a[m]){ 50 | r = m; 51 | }else{ 52 | l = m + 1; 53 | } 54 | }else if(a[m] <= a[r - 1]){ 55 | if(target >= a[m] && target <= a[r - 1]){ 56 | l = m + 1; 57 | }else{ 58 | r = m; 59 | } 60 | } 61 | } 62 | return -1; 63 | } 64 | 65 | //************************************************************ 66 | int findKth(int *a, int m, int a_start, int *b, int n, int b_start, int k){ 67 | if(a_start >= m) return b[b_start + k - 1]; 68 | if(b_start >= n) return a[a_start + k - 1]; 69 | if(k == 1) return min(a[a_start], b[b_start]); 70 | int a_val = (a_start + k / 2 - 1 < m) ? 71 | a[a_start + k / 2 - 1] : INT_MAX; 72 | int b_val = (b_start + k / 2 - 1 < n) ? 73 | b[b_start + k / 2 - 1] : INT_MAX; 74 | if(a_val < b_val){ 75 | return findKth(a, m, a_start + k / 2, b, n, b_start, k - k / 2); 76 | }else{ 77 | return findKth(a, m, a_start, b, n, b_start + k / 2, k - k / 2); 78 | } 79 | } 80 | 81 | double findMedianSortedArrays(int *a, int m, int *b, int n){ 82 | int len = m + n; 83 | if( len & 0x1){ 84 | return findKth(a, m, 0, b, n, 0, len / 2 + 1); 85 | }else{ 86 | return (findKth(a, m, 0, b, n, 0, len / 2) + findKth(a, m, 0, b, n, 0, len / 2 + 1)) >> 1; 87 | } 88 | } 89 | 90 | //************************************************************ 91 | 92 | int main() 93 | { 94 | int a[] = {4, 5, 6, 1, 2, 3}; 95 | int n = sizeof(a) / sizeof(*a); 96 | cout< 7 | using namespace std; 8 | 9 | /* 10 | * 对于线段树,在思考流程的时候可以以这种方式去思考 11 | [0,6) 12 | min* 13 | | | 14 | [0,3) [3,6) 15 | min* min* 16 | 17 | 区间+最值,这种方式去可视化思考过程. 18 | * */ 19 | 20 | const int kMaxTreeNodeNum = 1000; 21 | struct SegTreeNode { 22 | SegTreeNode() : val(0) { 23 | } 24 | 25 | int val; 26 | }g_seg_tree[kMaxTreeNodeNum]; 27 | 28 | // 如果区间超过1个元素,则左半边区间build到左子树,右半边build到右子树,然后当前根节点的值是 左右孩子的min 29 | // 如果区间只有一个值,则当前根节点的值就是这个元素的值 30 | // root: tree root position in the tree ndoe array 31 | // start: interval start 32 | // end: interval end 33 | void Build(int *arr, int root, int start, int end) { 34 | // base case 1: no element 35 | if (start >= end) { 36 | return; 37 | } 38 | 39 | // base case 2: only one element 40 | if (start + 1 == end) { 41 | g_seg_tree[root].val = arr[start]; 42 | return; 43 | } 44 | 45 | // iterative case 46 | int mid = start + (end - start) / 2; 47 | // build left child root 48 | Build(arr, 2*root+1, start, mid); 49 | // build right child root 50 | Build(arr, 2*root+2, mid, end); 51 | g_seg_tree[root].val = min(g_seg_tree[2*root+1].val, g_seg_tree[2*root+2].val); 52 | } 53 | 54 | // only in query, we can return a value, because we won't make any change to the tree 55 | int Query(int root, int start, int end, int query_start, int query_end) { 56 | if (query_start <= start && query_end >= end) { 57 | // 查询区间 包含 当前区间 58 | return g_seg_tree[root].val; 59 | } else if (query_start >= end || query_end <= start) { 60 | // 查询区间 和 当前区间 没有交集 61 | return INT_MAX; 62 | } 63 | 64 | int mid = start + (end - start) / 2; 65 | return min(Query(root*2+1, start, mid, query_start, query_end), 66 | Query(root*2+2, mid, end, query_start, query_end)); 67 | } 68 | 69 | // interval is left closed, right open 70 | void UpdateAt(int root, int start, int end, int pos, int new_val) { 71 | if (start >= end) { 72 | return; 73 | } 74 | 75 | if (start + 1 == end && start == pos) { 76 | g_seg_tree[root].val = new_val; 77 | return; 78 | } 79 | 80 | int mid = start + (end - start) / 2; 81 | if (pos < mid) { 82 | // left child root 83 | UpdateAt(2*root+1, start, mid, pos, new_val); 84 | } else { 85 | // right child root 86 | UpdateAt(2*root+2, mid, end, pos, new_val); 87 | } 88 | // update self using left and right 89 | g_seg_tree[root].val = min(g_seg_tree[2*root+1].val, g_seg_tree[2*root+2].val); 90 | } 91 | 92 | /****************************************************************************/ 93 | /* 94 | * Advanced and super simple implementation of Segment Tree 95 | * for int type 96 | * */ 97 | const int kMaxArrSize = 1e5; // 1e5 = 100,000 98 | int n; 99 | int t[2 * kMaxArrSize]; 100 | 101 | void build() { 102 | for (int i = n - 1; i > 0; --i) { 103 | t[i] = t[i>>1] + t[i>>1 | 1]; // i>>1 = i / 2, i>>1 | 1 = i / 2 + 1; 104 | } 105 | } 106 | 107 | void modify(int p, int val) { 108 | for (t[p+=n] = val; p > 1; p >>= 1) { 109 | // if p if left child, p^1 is right child, and vice versa 110 | t[p>>1] = t[p] + t[p^1]; 111 | } 112 | } 113 | 114 | // [l, r) 115 | int query(int l, int r) { 116 | int res = 0; 117 | for (l += n, r += n; l < r; l>>=1, r>>=1) { 118 | // 左边有落单的 119 | if (l&1) res += t[l++]; 120 | // 右边有落单的 121 | if (r&1) res += t[--r]; 122 | // 如果都没有落单的,则交由父节点去求和 123 | } 124 | 125 | return res; 126 | } 127 | 128 | 129 | int main() { 130 | int a[] = {2, 5, 1, 4, 9, 3}; 131 | //int n = sizeof(a) / sizeof(*a); 132 | int n = 6; 133 | Build(a, 0, 0, n); 134 | cout << Query(0, 0, n, 0, 3) << endl; 135 | UpdateAt(0, 0, n, 2, 10); 136 | cout << Query(0, 0, n, 0, 3) << endl; 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /ShortestPathDijkstra.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | const int VN = 5; 5 | 6 | class Graph{ 7 | public: 8 | Graph(); 9 | void shortestPathDijkstra(int , int); 10 | int choose(int); 11 | void addEdge(int s, int e, float weight); 12 | public: 13 | float edge[VN][VN]; 14 | float dist[VN]; 15 | int path[VN]; 16 | int s[VN]; // choose set 17 | }; 18 | 19 | Graph::Graph(){ 20 | for(int i = 0; i < VN; ++i){ 21 | for(int j = 0; j < VN; ++j){ 22 | edge[i][j] = INT_MAX; 23 | } 24 | } 25 | } 26 | 27 | void Graph::addEdge(int s, int e, float weight){ 28 | edge[s][e] = weight; 29 | } 30 | 31 | //1. initialize 2. add start 3. add loop (find min, add, update) 32 | void Graph::shortestPathDijkstra(int n, int v){ 33 | //1. initialize 34 | for(int i = 0; i < n; ++i){ 35 | dist[i] = edge[v][i]; 36 | s[i] = 0;// 1 mean added 37 | if(i != v && dist[i] < INT_MAX){ 38 | path[i] = v; 39 | }else{ 40 | path[i] = -1; 41 | } 42 | } 43 | //2. add start 44 | s[v] = 1; 45 | dist[v] = 0;//self to self distance is 0 46 | //3. add loop 47 | for(int i = 0; i < n - 1; ++i){//n - 1 vertex left except v 48 | float min_dist = INT_MAX; 49 | int u = v; 50 | for(int j = 0; j < n; ++j){ 51 | if(s[j] == 0 && dist[j] < min_dist){ 52 | u = j; 53 | min_dist = dist[j]; 54 | } 55 | } 56 | s[u] = 1;//v-u is the shortest 57 | 58 | //4. update the rest 59 | for(int w = 0; w < n; ++w){ 60 | if(s[w] == 0 && edge[u][w] < INT_MAX && dist[u] + edge[u][w] < dist[w]){ 61 | dist[w] = dist[u] + edge[u][w]; 62 | path[w] = u; 63 | } 64 | } 65 | } 66 | } 67 | 68 | int main() 69 | { 70 | Graph g; 71 | g.addEdge(0, 1, 30); 72 | g.addEdge(0, 3, 10); 73 | g.addEdge(0, 4, 50); 74 | g.addEdge(1, 2, 60); 75 | g.addEdge(1, 4, 80); 76 | g.addEdge(3, 4, 30); 77 | g.addEdge(4, 2, 40); 78 | g.addEdge(4, 0, 50); 79 | int start, end; 80 | cin>>start>>end; 81 | g.shortestPathDijkstra(VN, start); 82 | cout< 2 | using namespace std; 3 | 4 | const int VN = 5; 5 | const int MAXVALUE = 100000; 6 | class Graph{ 7 | public: 8 | Graph(); 9 | void addEdge(int s, int e, int weight); 10 | void floyd(int n); 11 | int edge[VN][VN]; 12 | int dist[VN][VN]; 13 | int path[VN][VN]; 14 | }; 15 | 16 | Graph::Graph(){ 17 | for(int i = 0; i < VN; ++i){ 18 | for(int j = 0; j < VN; ++j){ 19 | if(i == j) edge[i][j] = 0; 20 | else edge[i][j] = MAXVALUE; 21 | } 22 | } 23 | } 24 | 25 | void Graph::addEdge(int s, int e, int weight){ 26 | edge[s][e] = weight; 27 | } 28 | 29 | //1. initialize 2.iterative mid vertex 30 | void Graph::floyd(int n){ 31 | for(int i = 0; i < n; ++i){ 32 | for(int j = 0; j < n; ++j){ 33 | dist[i][j] = edge[i][j]; 34 | if(i != j && dist[i][j] < MAXVALUE){ 35 | path[i][j] = i; 36 | }else{ 37 | path[i][j] = -1; 38 | } 39 | } 40 | } 41 | 42 | for(int k = 0; k < n; ++k){ 43 | for(int i = 0; i < n; ++i){ 44 | for(int j = 0; j < n; ++j){ 45 | if(dist[i][k] < MAXVALUE && dist[k][j] < MAXVALUE 46 | &&dist[i][k] + dist[k][j] < dist[i][j]) 47 | { 48 | dist[i][j] = dist[i][k] + dist[k][j]; 49 | path[i][j] = path[k][j]; 50 | } 51 | } 52 | } 53 | } 54 | } 55 | 56 | int main() 57 | { 58 | Graph g; 59 | g.addEdge(0, 1, 30); 60 | g.addEdge(0, 3, 10); 61 | g.addEdge(0, 4, 50); 62 | g.addEdge(1, 2, 60); 63 | g.addEdge(1, 4, 80); 64 | g.addEdge(3, 4, 30); 65 | g.addEdge(4, 2, 40); 66 | g.addEdge(4, 0, 50); 67 | 68 | int start, end; 69 | cin>>start>>end; 70 | g.floyd(VN); 71 | cout< 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | //************************************************************ 7 | int partition(int *a, int start, int end){ 8 | int l = start, r = end - 1; 9 | const int pivot_val = a[l]; 10 | while(l < r){ 11 | while(l < r && a[r] >= pivot_val) --r; 12 | a[l] = a[r]; 13 | while(l < r && a[l] <= pivot_val) ++l; 14 | a[r] = a[l]; 15 | } 16 | a[l] = pivot_val; 17 | return l; 18 | } 19 | 20 | 21 | void quick_sort(int *a, int start, int end){ 22 | if(a == NULL) return ; 23 | 24 | if(start + 1 < end){ 25 | const int pivot_pos = partition(a, start, end); 26 | quick_sort(a, start, pivot_pos); 27 | quick_sort(a, pivot_pos + 1, end); 28 | } 29 | } 30 | 31 | //------------------------------------------------------------ 32 | //non recursive,左闭右开 33 | void quick_sort2(int *a, int start, int end){ 34 | stack stk; 35 | int l = start, r = end; 36 | if(l + 1 < r){ 37 | //part 1 38 | int pivot_pos = partition(a, l, r); 39 | if(l + 1 < pivot_pos){ 40 | stk.push(l); 41 | stk.push(pivot_pos); 42 | } 43 | if(pivot_pos + 1 + 1 < r){ 44 | stk.push(pivot_pos + 1); 45 | stk.push(r); 46 | } 47 | 48 | //part 2 49 | while(!stk.empty()){ 50 | r = stk.top(); 51 | stk.pop(); 52 | l = stk.top(); 53 | stk.pop(); 54 | 55 | //same with above 56 | pivot_pos = partition(a, l, r); 57 | if(l + 1 < pivot_pos){ 58 | stk.push(l); 59 | stk.push(pivot_pos); 60 | } 61 | if(pivot_pos + 1 + 1 < r){ 62 | stk.push(pivot_pos + 1); 63 | stk.push(r); 64 | } 65 | } 66 | } 67 | } 68 | 69 | 70 | //************************************************************ 71 | 72 | //k means dist to start 73 | int kth_small_num(int *a, int n, int start, int end, int k){ 74 | const int pivot_pos = partition(a, start, end); 75 | int dist = pivot_pos - start + 1; 76 | if(dist == k){ 77 | return a[pivot_pos]; 78 | }else if(dist < k){ 79 | return kth_small_num(a, n, pivot_pos + 1, end, k - dist); 80 | }else { 81 | return kth_small_num(a, n, start, pivot_pos, k); 82 | } 83 | } 84 | 85 | //************************************************************ 86 | void bubble_sort(int *a, int start, int end){ 87 | if(a == NULL) return ; 88 | bool exchange; 89 | for(int i = start; i < end - 1; ++i){ 90 | exchange = false; 91 | for(int j = end - 1; j > i; --j){ 92 | if(a[j] < a[j - 1]){ 93 | swap(a[j], a[j - 1]); 94 | exchange = true; 95 | } 96 | } 97 | if(!exchange) return; 98 | } 99 | } 100 | //************************************************************ 101 | void merge(int *a, int *tmp, int start, int mid, int end){ 102 | for(int i = start; i < end; ++i){ 103 | tmp[i] = a[i]; 104 | } 105 | int i = start, j = mid, k = start; 106 | while(i < mid && j < end){ 107 | if(tmp[i] < tmp[j]) a[k++] = tmp[i++]; 108 | else a[k++] = tmp[j++]; 109 | } 110 | while(i < mid) a[k++] = tmp[i++]; 111 | while(j < end) a[k++] = tmp[j++]; 112 | } 113 | 114 | void merge_sort(int *a, int *tmp, int start, int end){ 115 | if(a == NULL || tmp == NULL) return ; 116 | 117 | if(start + 1 < end){ 118 | int mid = start + ((end - start) >> 1); 119 | merge_sort(a, tmp, start, mid); 120 | merge_sort(a, tmp, mid, end); //mid should not plus 1 121 | merge(a, tmp, start, mid, end); 122 | } 123 | } 124 | 125 | //use merge sort to count reversion count 126 | int mrmerge(int *a, int *tmp, int start, int mid, int end){ 127 | for(int i = start; i < end; ++i) 128 | tmp[i] = a[i]; 129 | 130 | int i = mid - 1, j = end - 1, k = end - 1; 131 | int cnt = 0; 132 | while(i >= start && j >= mid){ 133 | if(tmp[i] > tmp[j]){ 134 | cnt += (j - mid + 1); 135 | a[k--] = tmp[i--]; 136 | }else{ 137 | a[k--] = tmp[j--]; 138 | } 139 | } 140 | 141 | while(i >= start) a[k--] = tmp[i--]; 142 | while(j >= mid) a[k--] = tmp[j--]; 143 | return cnt; 144 | } 145 | 146 | int mrcount(int *a, int *tmp, int start, int end){ 147 | if(a == NULL || tmp == NULL) return 0; 148 | if(start + 1 < end){ 149 | int mid = start + ((end - start) >> 1); 150 | int left = mrcount(a, tmp, start, mid); 151 | int right = mrcount(a, tmp, mid, end); 152 | int own = mrmerge(a, tmp, start, mid, end); 153 | return left + right + own; 154 | } 155 | return 0; 156 | } 157 | 158 | //************************************************************ 159 | void selection_sort(int *a, int start, int end){ 160 | if(a == NULL) return ; 161 | 162 | for(int i = start; i < end; ++i){ 163 | int min_idx = i; 164 | for(int j = i + 1; j < end; ++j){ 165 | if(a[j] < a[min_idx]) 166 | min_idx = j; 167 | } 168 | if(min_idx != i){ 169 | swap(a[i], a[min_idx]); 170 | } 171 | } 172 | } 173 | 174 | //************************************************************ 175 | void straight_insert_sort(int *a, int start, int end){ 176 | if(a == NULL) return ; 177 | 178 | int i, j; 179 | for(i = start + 1; i < end; ++i){ 180 | int tmp = a[i]; 181 | for(j = i - 1; j >= start && tmp < a[j] ; --j) 182 | a[j + 1] = a[j]; 183 | 184 | a[j + 1] = tmp; 185 | } 186 | } 187 | 188 | //************************************************************ 189 | void shell_insert(int *a, int start, int end, int gap){ 190 | int i, j; 191 | for(i = start + gap; i < end; ++i){ 192 | int tmp = a[i]; 193 | for(j = i - gap; j >= start && tmp < a[j]; j -= gap){ 194 | a[j + gap] = a[j]; 195 | } 196 | a[j + gap] = tmp; 197 | } 198 | 199 | } 200 | 201 | void shell_sort(int *a, int start, int end){ 202 | if(a == NULL) return; 203 | 204 | int gap = end - start; 205 | while(gap > 1){ 206 | gap = gap / 3 + 1; 207 | shell_insert(a, start, end, gap); 208 | } 209 | } 210 | 211 | //************************************************************ 212 | //array a range: 0 ~ k 213 | void counting_sort(int *a, int n, int k){ 214 | if(a == NULL) return; 215 | 216 | int *count = (int*) malloc(sizeof(int) * (k + 1)); 217 | memset(count, 0, sizeof(int) * (k + 1)); 218 | 219 | for(int i = 0; i < n; ++i) 220 | count[a[i]]++; 221 | 222 | for(int i = 1; i <= k; ++i) 223 | count[i] += count[i - 1]; 224 | 225 | int *b = (int*) malloc(sizeof(int) * n); 226 | for(int i = n - 1; i >= 0; --i){ 227 | b[count[a[i]] - 1] = a[i]; 228 | count[a[i]]--; 229 | } 230 | 231 | for(int i = 0; i < n; ++i) 232 | a[i] = b[i]; 233 | 234 | free(count); 235 | free(b); 236 | } 237 | 238 | //this one is much better 239 | void counting_sort2(int *a, int n, int k){ 240 | if(a == NULL) return; 241 | 242 | int *count = new int[k + 1](); 243 | for(int i = 0; i < n; ++i) 244 | count[a[i]]++; 245 | 246 | int j = 0; 247 | for(int i = 0; i <= k; ++i){ 248 | while(count[i]-- > 0){ 249 | a[j++] = i; 250 | } 251 | } 252 | 253 | delete[] count; 254 | } 255 | 256 | //************************************************************ 257 | //n: array number, rm: radius max, d: d-th digit 258 | void radix_counting_sort(int *a, int n, int radius_max, int d){ 259 | int *count = (int*) malloc(sizeof(int) * (radius_max + 1)); 260 | memset(count, 0, sizeof(int) * (radius_max + 1)); 261 | int *b = (int*)malloc(sizeof(int) * n); 262 | 263 | for(int i = 0; i < n; ++i){ 264 | int digit = (a[i] >> (d - 1)) & 1; 265 | count[digit]++; 266 | } 267 | 268 | for(int i = 1; i <= radius_max; ++i) 269 | count[i]+= count[i - 1]; 270 | 271 | // from end to start to ensure stable 272 | for(int i = n - 1; i >= 0; --i){ 273 | int digit = (a[i] >> (d - 1)) & 0x1; 274 | b[count[digit] - 1] = a[i]; 275 | count[digit]--; 276 | } 277 | 278 | for(int i = 0; i < n; ++i) 279 | a[i] = b[i]; 280 | 281 | free(count); 282 | free(b); 283 | } 284 | 285 | //d: 最大2进制的位数 286 | void radix_sort(int *a, int n, int d){ 287 | if(a == NULL) return ; 288 | 289 | for(int i = 1; i <= d; ++i){ 290 | radix_counting_sort(a, n, 1, i); 291 | } 292 | } 293 | 294 | int main(){ 295 | int a[] = {3, 5, 1, 4, 5, 6, 120, 23, 234}; 296 | const int n = sizeof(a) / sizeof(a[0]); 297 | quick_sort2(a, 0, n); 298 | for(int i = 0; i < n; ++i) 299 | cout< 2 | #include 3 | 4 | using namespace std; 5 | 6 | class StackUsingQueue{ 7 | public: 8 | void push(int x); 9 | void pop(); 10 | int top(); 11 | private: 12 | queue que1; 13 | queue que2; 14 | 15 | } 16 | 17 | void StackUsingQueue::push( int x ) 18 | { 19 | if (!que1.empty()) 20 | { 21 | que1.push(x); 22 | } 23 | else if(!que2.empty()) 24 | { 25 | que2.push(x); 26 | } 27 | else 28 | { 29 | que1.push(x); 30 | } 31 | } 32 | 33 | void StackUsingQueue::pop() 34 | { 35 | if (!que1.empty()) 36 | { 37 | int tmp; 38 | tmp = que1.front(); 39 | que1.pop(); 40 | while (!que1.empty()) 41 | { 42 | que2.push(tmp); 43 | tmp = que1.front(); 44 | que1.pop(); 45 | } 46 | } 47 | else if (!que2.empty()) 48 | { 49 | int tmp; 50 | tmp = que2.front(); 51 | que2.pop(); 52 | while (!que2.empty()) 53 | { 54 | que1.push(tmp); 55 | tmp = que2.front(); 56 | que2.pop(); 57 | } 58 | } 59 | } 60 | 61 | int StackUsingQueue::top() 62 | { 63 | if (!que1.empty()) 64 | { 65 | int tmp; 66 | while (!que1.empty()) 67 | { 68 | tmp = que1.front(); 69 | que1.pop(); 70 | que2.push(tmp); 71 | } 72 | return tmp; 73 | } 74 | else if (!que2.empty()) 75 | { 76 | int tmp; 77 | while (!que2.empty()) 78 | { 79 | tmp = que2.front(); 80 | que2.pop(); 81 | que1.push(tmp); 82 | } 83 | return tmp; 84 | } 85 | else 86 | { 87 | return INT_MAX; 88 | } 89 | } 90 | int main() 91 | { 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /StackWithMin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class StackWithMin{ 6 | public: 7 | void push(int key){ 8 | val_stk.push(key); 9 | if(min_stk.empty() || key <= min_stk.top()){ 10 | min_stk.push(key); 11 | } 12 | } 13 | 14 | void pop(){ 15 | if(!val_stk.empty()){ 16 | int t = val_stk.top(); 17 | val_stk.pop(); 18 | 19 | if(!min_stk.empty() && t <= min_stk.top()){ 20 | min_stk.pop(); 21 | } 22 | } 23 | } 24 | 25 | int top(){ 26 | if(!val_stk.empty()){ 27 | return val_stk.top(); 28 | }else{ 29 | return INT_MAX; 30 | } 31 | } 32 | int getMin(){ 33 | if(!min_stk.empty()){ 34 | return min_stk.top(); 35 | }else{ 36 | return INT_MAX; 37 | } 38 | } 39 | 40 | private: 41 | stack val_stk; 42 | stack min_stk; 43 | }; 44 | 45 | int main() 46 | { 47 | StackWithMin swm; 48 | for(int i = 0; i < 10; ++i){ 49 | int tmp = rand() % 20; 50 | swm.push(tmp); 51 | cout<<"push: " < 2 | #include 3 | #include 4 | #include 5 | #include // for class String 6 | using namespace std; 7 | 8 | char* strstr(char *txt, char *pat){ 9 | if(txt == NULL || pat == NULL) return NULL; 10 | int t_len = strlen(txt); 11 | int p_len = strlen(pat); 12 | 13 | int i, j; 14 | for(i = 0; i <= t_len - p_len; ++i){ 15 | for(j = i; j < p_len; ++j){ 16 | if(txt[i + j] != pat[j]) 17 | break; 18 | } 19 | if(j == p_len) return txt + i; 20 | } 21 | return NULL; 22 | } 23 | //************************************************************ 24 | void getNext(char *pat, int *next){ 25 | int m = strlen(pat); 26 | next[0] = -1; 27 | int i, j = -1; 28 | for(i = 1; i < m; ++i){ 29 | while(j > -1 && pat[i] != pat[j + 1]) j = next[j]; 30 | if(pat[i] == pat[j + 1]) j++; 31 | next[i] = j; 32 | } 33 | } 34 | 35 | void kmp(char *txt, char *pat){ 36 | if(txt == NULL || pat == NULL) return ; 37 | const int t_len = strlen(txt); 38 | const int p_len = strlen(pat); 39 | int *next = new int[p_len](); 40 | getNext(pat, next); 41 | 42 | int i, j = -1; 43 | for(i = 0; i < t_len; ++i){ 44 | while(j > -1 && txt[i] != pat[j + 1]) j = next[j]; 45 | if(txt[i] == pat[j + 1]) j++; 46 | if(j == p_len - 1){ 47 | cout<<"found: " << i - j + 1 <<" "; 48 | } 49 | } 50 | delete next; 51 | } 52 | 53 | //************************************************************ 54 | char* strcpy(char *to, char *from){ 55 | assert(to != NULL && from != NULL); 56 | char *p = to; 57 | while((*p++ = *from++) != '\0') ; 58 | return to; 59 | } 60 | 61 | //************************************************************ 62 | char* strcat(char *dst, const char *src){ 63 | if(dst == NULL || src == NULL) return dst; 64 | char *p = dst; 65 | while(*p != '\0') p++; 66 | while((*p++ = *src++) != '\0'); 67 | return dst; 68 | } 69 | 70 | //************************************************************ 71 | int strcmp(const char *str1, const char *str2){ 72 | while(*str1 == *str2){ 73 | if(*str1 =='\0') 74 | return 0; 75 | str1++, str2++; 76 | } 77 | return *str1 - *str2; 78 | } 79 | 80 | //************************************************************ 81 | void *memcpy(void *dst, const void *src, size_t count){ 82 | assert(dst != NULL && src != NULL); 83 | char *s_dst = (char*)dst, *s_src = (char*)src; 84 | for(size_t i = 0; i < count; ++i){ 85 | s_dst[i] = s_src[i]; 86 | } 87 | return s_dst; 88 | } 89 | 90 | //************************************************************ 91 | size_t strlen(const char *str){ 92 | const char *s; 93 | for(s = str; *s; ++s); 94 | return (s - str); 95 | } 96 | 97 | //************************************************************ 98 | void reverse(char *str, int s, int e){ 99 | if(str == NULL) return; 100 | while(s < e){ 101 | swap(str[s++], str[e--]); 102 | } 103 | } 104 | 105 | char* rightRotate(char *str, int k){ 106 | if(str == NULL) return NULL; 107 | 108 | int len = strlen(str); 109 | k %= len;// if k > len 110 | k = len - 1 - k; // find split position 111 | reverse(str, 0, k); 112 | reverse(str, k + 1, len - 1); 113 | reverse(str, 0, len - 1); 114 | return str; 115 | } 116 | 117 | char* leftRotate(char *str, int k){ 118 | if(str == NULL) return NULL; 119 | int len = strlen(str); 120 | k %= len; 121 | reverse(str, 0, k - 1); 122 | reverse(str, k, len - 1); 123 | reverse(str, 0, len - 1); 124 | return str; 125 | } 126 | //************************************************************ 127 | int longest_palindrome(const char *str){ 128 | if(str == NULL) return 0; 129 | const int len = strlen(str); 130 | int max_hui_len = 0; 131 | 132 | for(int i = 0; i < len; ++i){ 133 | int hui_len = 1; 134 | int l = i - 1, r = i + 1; //odd 135 | while(l >= 0 && r < len && str[l] == str[r]) 136 | l--, r++; 137 | hui_len = r - l + 1 - 2; 138 | max_hui_len = max(hui_len, max_hui_len); 139 | 140 | l = i, r = i + 1; //even 141 | while(l >= 0 && r < len && str[l] == str[r]) 142 | l--, r++; 143 | 144 | hui_len = r - l + 1 - 2; 145 | max_hui_len = max(hui_len, max_hui_len); 146 | } 147 | return max_hui_len; 148 | } 149 | 150 | 151 | //stl 中 string的源代码, stl 中string 是小写的 152 | class String{ 153 | private: 154 | unsigned len; 155 | char *pbuf; 156 | public: 157 | String() : len(0), pbuf(0){} 158 | String(const String&); 159 | String& operator=(const String&); 160 | ~String(); 161 | 162 | String(const char * str); 163 | String& operator=(const char *s); 164 | 165 | const char& operator[](unsigned idx) const; 166 | char& operator[](unsigned idx); 167 | 168 | bool operator==(const String &other); 169 | String operator+(const String &other) const; // return value, not reference 170 | 171 | const char* c_str() const; 172 | unsigned length() const; 173 | unsigned size() const; 174 | friend ostream& operator<<(ostream &os, const String &s); 175 | friend istream& operator>>(istream &is, String &s); 176 | }; 177 | 178 | String::String(const char *str) : len(0), pbuf(0){ 179 | *this = str; 180 | } 181 | 182 | String::String(const String &s) : len(0), pbuf(0){ 183 | *this = s; 184 | } 185 | 186 | String::~String(){ 187 | if(pbuf != 0){ 188 | delete[] pbuf; 189 | pbuf = 0; 190 | } 191 | } 192 | //this is not the best, use "copy and swap" is better to avoid exception in new operator 193 | String& String::operator=(const char *s){ 194 | this->~String(); 195 | len = strlen(s); 196 | pbuf = strcpy(new char[len + 1], s); 197 | return *this; 198 | } 199 | 200 | String& String::operator=(const String &s){ 201 | if(&s == this) 202 | return *this; 203 | this->~String(); 204 | len = s.len; 205 | pbuf = strcpy(new char[len + 1], s.pbuf); 206 | return *this; 207 | } 208 | 209 | const char& String::operator[](unsigned idx) const{ 210 | return pbuf[idx]; 211 | } 212 | 213 | char& String::operator[](unsigned idx){ 214 | return pbuf[idx]; 215 | } 216 | 217 | String String::operator+(const String &other) const{ 218 | String newString; 219 | if(other.pbuf == NULL){ 220 | newString = *this; 221 | }else if(this->pbuf == NULL){ 222 | newString = other; 223 | }else{ 224 | newString.pbuf = new char[strlen(pbuf) + strlen(other.pbuf) + 1]; 225 | strcpy(newString.pbuf, pbuf); 226 | strcat(newString.pbuf, other.pbuf); 227 | } 228 | return newString; 229 | } 230 | 231 | bool String::operator==(const String &other){ 232 | if(strlen(pbuf) != strlen(other.pbuf)) return false; 233 | else return (strcmp(pbuf, other.pbuf) == 0 ? true : false); 234 | } 235 | 236 | const char* String::c_str() const{ 237 | return pbuf; 238 | } 239 | 240 | unsigned String::length() const{ 241 | return len; 242 | } 243 | 244 | unsigned String::size() const{ 245 | return len; 246 | } 247 | 248 | ostream& operator<<(ostream &os, const String &s){ 249 | os<>(istream &is, String &s){ 254 | //cout<<"here: " <>setw(256)>>temp; 257 | s = temp; 258 | return is; 259 | } 260 | 261 | int main() 262 | { 263 | String s1 = "hello"; 264 | String s2 = "hello"; 265 | cout<<(s1 == s2) < 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct TreeNode{ 9 | int val; 10 | TreeNode *lchild, *rchild; 11 | TreeNode(int x) : val(x), lchild(NULL), rchild(NULL){} 12 | TreeNode(TreeNode *l = NULL, TreeNode *r = NULL): lchild(l), rchild(r){} 13 | }; 14 | 15 | TreeNode* createTree(){ 16 | TreeNode *T; 17 | int data; 18 | cin>>data; 19 | if(data == -1){ 20 | T = NULL; 21 | }else{ 22 | T = new TreeNode(data); 23 | T->lchild = createTree(); 24 | T->rchild = createTree(); 25 | } 26 | return T; 27 | } 28 | 29 | //************************************************************ 30 | //1 while 31 | void preOrder(TreeNode *root){ 32 | if(root == NULL) return ; 33 | stack stk; 34 | TreeNode *p = root; 35 | stk.push(p);//no need for inOrder and postOrder 36 | while(!stk.empty()){ 37 | p = stk.top(); 38 | stk.pop(); 39 | cout<val<<" "; 40 | 41 | if(p->rchild != NULL) stk.push(p->rchild); 42 | if(p->lchild != NULL) stk.push(p->lchild); 43 | } 44 | } 45 | //2 while 46 | void inOrder(TreeNode *root){ 47 | if(root == NULL) return ; 48 | stack stk; 49 | TreeNode *p = root; 50 | while(!stk.empty() || p != NULL){ 51 | //left 52 | while(p != NULL){ 53 | stk.push(p); 54 | p = p->lchild; 55 | } 56 | //self 57 | p = stk.top(); 58 | stk.pop(); 59 | cout<val <<" "; 60 | //right 61 | p = p->rchild; 62 | } 63 | } 64 | 65 | //3 while, 1 do 66 | void postOrder(TreeNode *root){ 67 | if(root == NULL) return; 68 | stack stk; 69 | TreeNode *p, *q; 70 | p = root; 71 | do{ 72 | while(p != NULL){ 73 | stk.push(p); 74 | p = p->lchild; 75 | }//left most 76 | 77 | q = NULL; 78 | while(!stk.empty()){ 79 | p = stk.top(); 80 | stk.pop(); 81 | 82 | if(q == p->rchild){ 83 | cout<val<<" "; 84 | q = p; 85 | }else{ 86 | stk.push(p); 87 | p = p->rchild; 88 | break;//important 89 | } 90 | } 91 | }while(!stk.empty()); 92 | } 93 | 94 | void levelOrder(TreeNode *root){ 95 | if(root == NULL) return; 96 | queue que; 97 | TreeNode *p = root; 98 | que.push(p); 99 | while(!que.empty()){ 100 | int level_size = que.size(); 101 | for(int i = 0; i < level_size; ++i){ 102 | p = que.front(); 103 | que.pop(); 104 | cout<val <<" "; 105 | 106 | if(p->lchild != NULL) que.push(p->lchild); 107 | if(p->rchild != NULL) que.push(p->rchild); 108 | } 109 | cout< que; 116 | TreeNode *p = root; 117 | que.push(p); 118 | while(!que.empty()){ 119 | p = que.front(); 120 | que.pop(); 121 | cout<val <<" "; 122 | 123 | if(p->lchild != NULL) que.push(p->lchild); 124 | if(p->rchild != NULL) que.push(p->rchild); 125 | } 126 | } 127 | 128 | void dfs(TreeNode *root){ 129 | if(root == NULL) return; 130 | stack stk; 131 | TreeNode *p = root; 132 | stk.push(p); 133 | while(!stk.empty()){ 134 | p = stk.top(); 135 | stk.pop(); 136 | cout<val <<" "; 137 | 138 | if(p->rchild != NULL) stk.push(p->rchild); 139 | if(p->lchild != NULL) stk.push(p->lchild); 140 | } 141 | } 142 | 143 | //************************************************************ 144 | //recursive 145 | void insertBST(TreeNode *&root, TreeNode *newNode){ 146 | if(root == NULL) 147 | root = newNode; 148 | else if(newNode->val < root->val) 149 | insertBST(root->lchild, newNode); 150 | else if(newNode->val > root->val) 151 | insertBST(root->rchild, newNode); 152 | } 153 | 154 | bool searchBST(TreeNode *root, int target){ 155 | if(root == NULL) return false; 156 | 157 | if(target < root->val){ 158 | return searchBST(root->lchild, target); 159 | }else if(target > root->val){ 160 | return searchBST(root->rchild, target); 161 | }else{ 162 | return true; 163 | } 164 | } 165 | 166 | //************************************************************ 167 | TreeNode* createBST(){ 168 | TreeNode *root = NULL; 169 | int data; 170 | while(cin>>data){ 171 | TreeNode *t = new TreeNode(data); 172 | insertBST(root, t); 173 | } 174 | return root; 175 | } 176 | 177 | //************************************************************ 178 | //iterative 179 | //remember this instead of above 180 | TreeNode* searchBSTIterative(TreeNode *root, int val){ 181 | TreeNode *p = root; 182 | while(p != NULL){ 183 | if(val < p->val){ 184 | p = p->lchild; 185 | }else if(val > p->val){ 186 | p = p->rchild; 187 | }else{ 188 | return p; 189 | } 190 | } 191 | return NULL; 192 | } 193 | 194 | bool insertBSTIterative(TreeNode *&root, int val){ 195 | TreeNode *par = NULL; 196 | TreeNode *cur = root; 197 | while(cur != NULL){ 198 | if(val < cur->val){ 199 | par = cur; 200 | cur = cur->lchild; 201 | }else if (val > cur->val){ 202 | par = cur; 203 | cur = cur->rchild; 204 | }else{ 205 | return false;//如果BST中存在相同则返回false 206 | } 207 | } 208 | 209 | TreeNode *newNode = new TreeNode(val); 210 | if(par == NULL){ 211 | root = newNode; 212 | }else{ 213 | if(val > par->val){ 214 | par->rchild = newNode; 215 | }else{ 216 | par->lchild = newNode; 217 | } 218 | } 219 | return true; 220 | } 221 | 222 | //************************************************************ 223 | //Given two values, print all the keys in Balanced Search Tree in the range in increasing order 224 | void searchRangeInBSTHelper(TreeNode *root, vector &result, int &low, int &high){ 225 | if(root == NULL) return; 226 | 227 | if(root->val >= low && root->val <= high){ 228 | searchRangeInBSTHelper(root->lchild, result, low, high); 229 | result.push_back(root->val); 230 | searchRangeInBSTHelper(root->rchild, result, low, high); 231 | }else if(root->val > high){ 232 | searchRangeInBSTHelper(root->lchild, result, low, high); 233 | }else if(root->val < low){ 234 | searchRangeInBSTHelper(root->rchild, result, low, high); 235 | } 236 | } 237 | 238 | vector searchRangeInBST(TreeNode *root, int low, int high){ 239 | vector result; 240 | if(root == NULL) return result; 241 | 242 | searchRangeInBSTHelper(root, result, low, high); 243 | return result; 244 | } 245 | 246 | //************************************************************ 247 | //You need to find the inorder successor and predecessor of a given key. 248 | //In case the given key is not found in BST, 249 | //then return the two values within which this key will lie. 250 | //Following is the algorithm to reach the desired result. Its a recursive method: 251 | void findPrevSuc(TreeNode *root, TreeNode *&prev, TreeNode *&suc, int key){ 252 | if(root == NULL) return ; 253 | 254 | if(root->val == key){ 255 | if(root->lchild != NULL){ 256 | TreeNode *tmp = root->lchild; 257 | while(tmp->rchild != NULL) 258 | tmp = tmp->rchild; 259 | prev = tmp; 260 | } 261 | 262 | if(root->rchild != NULL){ 263 | TreeNode *tmp = root->rchild; 264 | while(tmp->lchild != NULL) 265 | tmp = tmp->lchild; 266 | suc = tmp; 267 | } 268 | }else if(root->val > key){//go left 269 | suc = root; 270 | findPrevSuc(root->lchild, prev, suc, key); 271 | }else{//go right 272 | prev = root; 273 | findPrevSuc(root->rchild, prev, suc, key); 274 | } 275 | } 276 | 277 | //************************************************************ 278 | bool delNode(TreeNode *&node){ 279 | TreeNode *par; 280 | if(node->rchild == NULL){ 281 | par = node; node = node->lchild;free(par); 282 | }else if(node->lchild == NULL){ 283 | par = node; node = node->rchild; free(par); 284 | }else{//internal node 285 | par = node; 286 | TreeNode *tmp = node->lchild; 287 | while(tmp->rchild != NULL){ 288 | par = tmp;//update parent 289 | tmp = tmp->rchild; 290 | } 291 | node->val = tmp->val;//replace 292 | if(par == node){ 293 | par->lchild = tmp->lchild; 294 | }else{ 295 | par->rchild = tmp->lchild; 296 | } 297 | free(tmp); 298 | } 299 | return true; 300 | } 301 | 302 | bool delBST(TreeNode *&root, int val){ 303 | if(root == NULL) return false; 304 | 305 | if(val < root->val){ 306 | return delBST(root->lchild, val); 307 | }else if(val > root->val){ 308 | return delBST(root->rchild, val); 309 | }else{ 310 | return delNode(root); 311 | } 312 | } 313 | 314 | //************************************************************ 315 | bool isValid(TreeNode *root, int lower, int upper){ 316 | if(root == NULL) return true; 317 | return (root->val > lower) && (root->val < upper) 318 | &&isValid(root->lchild, lower, root->val) 319 | &&isValid(root->rchild, root->val, upper); 320 | } 321 | 322 | bool isValidBST(TreeNode* root){ 323 | return isValid(root, INT_MIN, INT_MAX); 324 | } 325 | 326 | //************************************************************ 327 | // 修改一下GetHeight的函数,加入平衡的返回结果作为参数即可 328 | int GetHeight(TreeNode *root, bool &is_balanced){ 329 | if(root == NULL) return 0; 330 | if(!is_balanced) return 0; 331 | 332 | int lh = GetHeight(root->lchild, is_balanced); 333 | int rh = GetHeight(root->rchild, is_balanced); 334 | if(!is_balanced) return 0;//if is_balanced has been change in above two lines 335 | is_balanced = abs(lh - rh) <= 1; 336 | return max(lh, rh) + 1; 337 | } 338 | 339 | bool isBalanced(TreeNode *root){ 340 | bool is_balanced = true; 341 | GetHeight(root, is_balanced); 342 | return is_balanced; 343 | } 344 | 345 | //************************************************************ 346 | int treeDepth(TreeNode *root){ 347 | if(root == NULL) return 0; 348 | return max(treeDepth(root->lchild), treeDepth(root->rchild)) + 1; 349 | } 350 | 351 | //************************************************************ 352 | int minDepth(TreeNode *root){ 353 | if(root == NULL) return 0; 354 | int ld = minDepth(root->lchild); 355 | int rd = minDepth(root->rchild); 356 | if(ld == 0){ 357 | return rd + 1; 358 | }else if(rd == 0){ 359 | return ld + 1; 360 | }else{ 361 | return min(ld, rd) + 1; 362 | } 363 | } 364 | 365 | int maxDepth(TreeNode *root){ 366 | if(root == NULL) return 0; 367 | int ld = maxDepth(root->lchild); 368 | int rd = maxDepth(root->rchild); 369 | if(ld == 0){ 370 | return rd + 1; 371 | }else if(rd == 0){ 372 | return ld + 1; 373 | }else{ 374 | return max(ld, rd) + 1; 375 | } 376 | } 377 | 378 | //************************************************************ 379 | bool isSameTree(TreeNode *r1, TreeNode *r2){ 380 | if(r1 == NULL && r2 == NULL) return true; 381 | else if(r1 == NULL || r2 == NULL) return false; 382 | 383 | return (r1->val == r2->val) 384 | && isSameTree(r1->lchild, r2->lchild) 385 | && isSameTree(r1->rchild, r2->rchild); 386 | } 387 | 388 | //************************************************************ 389 | bool isSymmetricTree(TreeNode *lchild, TreeNode *rchild){ 390 | if(lchild == NULL && rchild == NULL) return true; 391 | else if(lchild == NULL || rchild == NULL) return false; 392 | 393 | return lchild->val == rchild->val 394 | && isSymmetricTree(lchild->lchild, rchild->rchild) 395 | && isSymmetricTree(lchild->rchild, rchild->lchild); 396 | } 397 | 398 | bool isSymmetricTree(TreeNode *root){ 399 | if(root == NULL) return true; 400 | else return isSymmetricTree(root->lchild, root->rchild); 401 | } 402 | 403 | //************************************************************ 404 | //破坏原来的树 405 | TreeNode* getSymmetricTree(TreeNode *&root){ 406 | if(root == NULL) return root; 407 | 408 | TreeNode *l = getSymmetricTree(root->lchild); 409 | TreeNode *r = getSymmetricTree(root->rchild); 410 | root->lchild = r; 411 | root->rchild = l; 412 | return root; 413 | } 414 | //不破坏原来的树 415 | TreeNode* getSymmetricTree2(TreeNode *root){ 416 | if(root == NULL) return root; 417 | 418 | TreeNode *rootCopy = new TreeNode(root->val); 419 | rootCopy->lchild = getSymmetricTree2(rootCopy->rchild); 420 | rootCopy->rchild = getSymmetricTree2(rootCopy->lchild); 421 | return rootCopy; 422 | } 423 | //************************************************************ 424 | void destroyTree(TreeNode *root){ 425 | if(root == NULL) 426 | return; 427 | destroyTree(root->lchild); 428 | destroyTree(root->rchild); 429 | delete root; 430 | } 431 | 432 | ///////////////////////////advanced////////////////////////// 433 | //************************************************************ 434 | //完全二叉树 435 | bool isCompleteTree(TreeNode *root){ 436 | if(root == NULL) return true; 437 | 438 | queue que; 439 | TreeNode *p = root; 440 | que.push(p); 441 | bool see_unfull = false; 442 | while(!que.empty()){ 443 | p = que.front(); 444 | que.pop(); 445 | 446 | //left 447 | if(p->lchild != NULL){ 448 | if(see_unfull) return false; 449 | else que.push(p->lchild); 450 | }else{ 451 | see_unfull = true; 452 | } 453 | //right 454 | if(p->rchild != NULL){ 455 | if(see_unfull) return false; 456 | else que.push(p->rchild); 457 | }else{ 458 | see_unfull = true; 459 | } 460 | } 461 | return true; 462 | } 463 | 464 | //https://oj.leetcode.com/problems/flatten-binary-tree-to-linked-list/ 465 | //not in ordered 466 | void flatten(TreeNode *root){ 467 | if(root == NULL) return; 468 | 469 | flatten(root->lchild); 470 | flatten(root->rchild); 471 | 472 | //flatten process 473 | if(root->lchild != NULL){ 474 | TreeNode *tmp = root->lchild; 475 | while(tmp->rchild != NULL) 476 | tmp = tmp->rchild; 477 | 478 | tmp->rchild = root->rchild; 479 | root->rchild = tmp; 480 | root->lchild = NULL; 481 | } 482 | } 483 | 484 | //http://www.cnblogs.com/remlostime/archive/2012/10/29/2745300.html 485 | //convert BST to double linked list 486 | TreeNode convert(TreeNode *root){ 487 | if(root == NULL){ 488 | return TreeNode(); 489 | } 490 | 491 | //flatten process 492 | TreeNode ltree = convert(root->lchild); 493 | TreeNode rtree = convert(root->rchild); 494 | root->lchild = ltree.rchild;//left 495 | if(ltree.rchild != NULL) 496 | ltree.rchild->rchild = root; 497 | 498 | root->rchild = rtree.lchild;//right 499 | if(rtree.lchild != NULL) 500 | rtree.lchild->lchild = root; 501 | 502 | //as whole 503 | TreeNode *l = ltree.lchild == NULL ? root : ltree.lchild; 504 | TreeNode *r = rtree.rchild == NULL ? root : rtree.rchild; 505 | return TreeNode(l, r); 506 | } 507 | 508 | TreeNode* convert2DoubleList(TreeNode *root){ 509 | TreeNode ret = convert(root); 510 | return ret.lchild; 511 | } 512 | 513 | //test program 514 | // TreeNode *bst = createBST(); 515 | // TreeNode *h = convert2DoubleList(bst); 516 | // while(h != NULL){ 517 | // cout<val <<" "; 518 | // h = h->rchild; 519 | // } 520 | // cout<lchild == sun || root->rchild == sun) return true; 529 | 530 | return IsFather(root->lchild, sun) || IsFather(root->rchild, sun); 531 | } 532 | 533 | void LCA(TreeNode *root, TreeNode *s1, TreeNode *s2, TreeNode *&ans) { 534 | if (root == NULL || s1 == NULL || s2 == NULL) 535 | return; 536 | 537 | // only both father, we need go deeper 538 | // if not, recursive process ends 539 | if (IsFather(root, s1) && IsFather(root, s2)) { 540 | ans = root; 541 | LCA(root->lchild, s1, s2, ans); 542 | LCA(root->rchild, s1, s2, ans); 543 | } 544 | } 545 | 546 | // an easier case, get the LCA on binary search tree, assume s1->val <= s2->val 547 | void BSTLCA(TreeNode *root, int small, int big, TreeNode *&ans) { 548 | if (root == NULL) { 549 | return; 550 | } 551 | 552 | while (root != NULL) { 553 | if (root->val >= small && root->val <= big) { 554 | ans = root; 555 | return; 556 | } else if (big < root->val) { 557 | root = root->lchild; 558 | } else if (small > root->val) { 559 | root = root->rchild; 560 | } 561 | } 562 | 563 | return; 564 | } 565 | 566 | //************************************************************ 567 | //树中两节点间的最大距离 568 | 569 | 570 | //************************************************************ 571 | //build tree from preorder and inorder 572 | TreeNode* build(vector &preorder, int pl, int pr, 573 | vector &inorder, int il, int ir){ 574 | TreeNode *root; 575 | if(pl > pr || il > ir){ 576 | root = NULL; 577 | }else { 578 | root = new TreeNode(preorder[pl]); 579 | int i; 580 | for(i = il; i <= ir && inorder[i] != root->val; ++i) 581 | ; 582 | root->lchild = build(preorder, pl + 1, pl + i - il, inorder, il, i - 1); 583 | root->rchild = build(preorder, pl + i - il + 1, pr, inorder, i + 1, ir); 584 | } 585 | return root; 586 | } 587 | 588 | TreeNode* buildTree(vector &preorder, vector &inorder){ 589 | return build(preorder, 0, preorder.size() - 1, 590 | inorder, 0, inorder.size() - 1); 591 | } 592 | 593 | //************************************************************ 594 | //build tree from inorder and postorder 595 | TreeNode* build2(vector &inorder, int il, int ir, 596 | vector &postorder, int pl, int pr){ 597 | TreeNode *root; 598 | if(il > ir || pl > pr){ 599 | root = NULL; 600 | }else{ 601 | root = new TreeNode(postorder[pr]); 602 | int i; 603 | for(i = il; i <= ir && inorder[i] != root->val; ++i) 604 | ; 605 | root->lchild = build(inorder, il, i - 1, postorder, pl, i - il + pl - 1); 606 | root->rchild = build(inorder, i + 1, ir, postorder, i - il + pl, pr - 1); 607 | } 608 | return root; 609 | } 610 | 611 | 612 | //************************************************************ 613 | /* 614 | * * 12. 求二叉树中节点的最大距离:getMaxDistanceRec 615 | * 616 | * 首先我们来定义这个距离: 617 | * 距离定义为:两个节点间边的数目. 618 | * 如: 619 | * 1 620 | * / \ 621 | * 2 3 622 | * \ 623 | * 4 624 | * 这里最大距离定义为2,4的距离,为3. 625 | * 求二叉树中节点的最大距离 即二叉树中相距最远的两个节点之间的距离。 (distance / diameter) 626 | * 递归解法: 627 | * 返回值设计: 628 | * 返回1. 深度, 2. 当前树的最长距离 629 | * (1) 计算左子树的深度,右子树深度,左子树独立的链条长度,右子树独立的链条长度 630 | * (2) 最大长度为三者之最: 631 | * a. 通过根节点的链,为左右深度+2 632 | * b. 左子树独立链 633 | * c. 右子树独立链。 634 | * 635 | * (3)递归初始条件: 636 | * 当root == null, depth = -1.maxDistance = -1; 637 | */ 638 | struct Result{ 639 | int maxDist; 640 | int depth; 641 | Result(int dist = -1, int depth = -1) : maxDist(dist), depth(depth){} 642 | }; 643 | 644 | Result getMaxDistHelper(TreeNode *root){ 645 | Result res; 646 | if(root == NULL) return res; 647 | 648 | Result l = getMaxDistHelper(root->lchild); 649 | Result r = getMaxDistHelper(root->rchild); 650 | res.depth = max(l.depth, r.depth) + 1;//1.update depth 651 | 652 | int cross = l.depth + 1 + r.depth + 1;//对于一个跨点的路径,跟左右的最大深度有关 653 | res.maxDist = max(cross, max(l.maxDist, r.maxDist));//2.update max dist 654 | return res; 655 | } 656 | 657 | int getMaxDist(TreeNode *root){ 658 | return getMaxDistHelper(root).maxDist; 659 | } 660 | 661 | //************************************************************ 662 | 663 | 664 | int main() 665 | { 666 | //ifstream in("input.txt"); 667 | //cin.rdbuf(in.rdbuf()); 668 | TreeNode *t = createBST(); 669 | int small = 4, big = 14; 670 | TreeNode *ans = NULL; 671 | BSTLCA(t, small, big, ans); 672 | if (ans != NULL) { 673 | cout << ans->val << endl; 674 | } 675 | //in.close(); 676 | return 0; 677 | } 678 | -------------------------------------------------------------------------------- /UnionFind.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int MAX_NUM = 10; 6 | 7 | int cnt = 0; 8 | int id[MAX_NUM]; 9 | 10 | void init(){ 11 | cnt = MAX_NUM; 12 | for(int i = 0; i < MAX_NUM; ++i){ 13 | id[i] = i; 14 | } 15 | } 16 | 17 | int find(int p){ 18 | return id[p]; 19 | } 20 | 21 | bool connected(int p, int q){ 22 | return find(p) == find(q); 23 | } 24 | 25 | void myunion(int p, int q){ 26 | int pid = find(p); 27 | int qid = find(q); 28 | if(pid == qid) return ; 29 | for(int i = 0; i < MAX_NUM; ++i){ 30 | if(id[i] == pid) 31 | id[i] = qid; 32 | } 33 | cnt--; 34 | } 35 | 36 | int main() 37 | { 38 | ifstream in; 39 | in.open("uf.txt"); 40 | cin.rdbuf(in.rdbuf()); 41 | 42 | int a, b; 43 | init(); 44 | while(cin>>a>>b){ 45 | if(connected(a, b)) continue; 46 | myunion(a, b); 47 | } 48 | cout< 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | const bool RED = true; 8 | const bool BLACK = false; 9 | 10 | struct TreeNode{ 11 | int val; 12 | TreeNode *lchild, *rchild; 13 | bool color;//red: 1, black: 0 14 | int N; 15 | TreeNode(int x, bool c, int s) : val(x), lchild(NULL), rchild(NULL), color(c), N(s){} 16 | }; 17 | 18 | //************************************************************ 19 | //basic operations 20 | bool isRed(TreeNode *root){ 21 | if(root == NULL) return false; 22 | else return root->color == RED; 23 | } 24 | 25 | int size(TreeNode *root){ 26 | if(root == NULL) return 0; 27 | else return root->N; 28 | } 29 | 30 | TreeNode* rotateLeft(TreeNode *root){ 31 | assert(root != NULL && isRed(root->rchild)); 32 | //link 33 | TreeNode *rc = root->rchild; 34 | root->rchild = rc->lchild; 35 | rc->lchild = root; 36 | //color 37 | rc->color = root->color; 38 | root->color = RED; 39 | //size 40 | rc->N = root->N; 41 | root->N = size(root->lchild) + size(root->rchild) + 1; 42 | return rc; 43 | } 44 | 45 | TreeNode* rotateRight(TreeNode *root){ 46 | assert(root != NULL && isRed(root->lchild)); 47 | //link 48 | TreeNode *lc = root->lchild; 49 | root->lchild = lc->rchild; 50 | lc->rchild = root; 51 | //color 52 | lc->color = root->color; 53 | root->color = RED; 54 | //size 55 | lc->N = root->N; 56 | root->N = size(root->lchild) + size(root->rchild) + 1; 57 | return lc; 58 | } 59 | 60 | void flipColors(TreeNode *root){ 61 | assert(root != NULL && root->lchild != NULL && root->rchild != NULL); 62 | // h must have opposite color of its two children 63 | assert ((isRed(root) && !isRed(root->lchild) && !isRed(root->rchild)) 64 | || (!isRed(root) && isRed(root->lchild) && isRed(root->rchild)) ); 65 | 66 | root->color = !root->color; 67 | root->lchild->color = !root->lchild->color; 68 | root->rchild->color = !root->rchild->color; 69 | } 70 | 71 | //************************************************************ 72 | void insert(TreeNode *&root, TreeNode *newNode){ 73 | if(root == NULL) 74 | root = newNode; 75 | 76 | if(newNode->val < root->val){ 77 | insert(root->lchild, newNode); 78 | }else if(newNode->val > root->val){ 79 | insert(root->rchild, newNode); 80 | }else{ 81 | root->val = newNode->val;//overwrite the value 82 | } 83 | 84 | if(isRed(root->rchild) && !isRed(root->lchild)) root = rotateLeft(root); 85 | if(isRed(root->lchild) && root->lchild != NULL && isRed(root->lchild->lchild)) root = rotateRight(root); 86 | if(isRed(root->lchild) && isRed(root->rchild)) flipColors(root); 87 | root->N = size(root->lchild) + size(root->rchild) + 1; 88 | } 89 | 90 | 91 | TreeNode* createRBTree(int n){ 92 | TreeNode *root = NULL; 93 | for(int i = 0; i < n; ++i){ 94 | TreeNode *newNode = new TreeNode(i, RED, 1); 95 | insert(root, newNode); 96 | root->color = BLACK;//every time insert, label the root as BLACK 97 | } 98 | return root; 99 | } 100 | 101 | //************************************************************ 102 | bool search(TreeNode *root, int target){ 103 | while(root != NULL){ 104 | if(target == root->val){ 105 | return true; 106 | }else if(target > root->val){ 107 | return search(root->rchild, target); 108 | }else { 109 | return search(root->lchild, target); 110 | } 111 | } 112 | return false; 113 | } 114 | 115 | //************************************************************ 116 | //rank k means: in inorder traversal, there are k nodes smaller than it; 117 | TreeNode* selectRank(TreeNode *root, int k){ 118 | assert(root != NULL && k >= 0); 119 | 120 | int t = size(root->lchild); 121 | if(k > t) return selectRank(root->rchild, k - t - 1); 122 | else if(k < t) return selectRank(root->lchild, k); 123 | else return root; 124 | } 125 | 126 | //************************************************************ 127 | //assume no duplicates, return the rank of the target value 128 | int getRank(TreeNode *root, int target){ 129 | if(root == NULL) return 0; 130 | 131 | if(target > root->val){ 132 | return size(root->lchild) + 1 + getRank(root->rchild, target); 133 | }else if(target < root->val){ 134 | return getRank(root->lchild, target); 135 | }else{ 136 | return size(root->lchild); 137 | } 138 | } 139 | 140 | //************************************************************ 141 | void preOrder(TreeNode *root){ 142 | if(root == NULL) return ; 143 | stack stk; 144 | TreeNode *p = root; 145 | stk.push(p);//no need for inOrder and postOrder 146 | while(!stk.empty()){ 147 | p = stk.top(); 148 | stk.pop(); 149 | cout<val<<" "<<"size: " << p->N<rchild != NULL) stk.push(p->rchild); 152 | if(p->lchild != NULL) stk.push(p->lchild); 153 | } 154 | } 155 | 156 | int main() 157 | { 158 | TreeNode *root = createRBTree(5); 159 | preOrder(root); 160 | int n; 161 | while(cin>>n){ 162 | cout< 7 | using namespace std; 8 | 9 | /* 10 | * 对于线段树,在思考流程的时候可以以这种方式去思考 11 | [0,6) 12 | min* 13 | | | 14 | [0,3) [3,6) 15 | min* min* 16 | 17 | 区间+最值,这种方式去可视化思考过程. 18 | * */ 19 | 20 | const int kMaxTreeNodeNum = 1000; 21 | struct SegTreeNode { 22 | SegTreeNode() : val(0) { 23 | } 24 | 25 | int val; 26 | }g_seg_tree[kMaxTreeNodeNum]; 27 | 28 | // 如果区间超过1个元素,则左半边区间build到左子树,右半边build到右子树,然后当前根节点的值是 左右孩子的min 29 | // 如果区间只有一个值,则当前根节点的值就是这个元素的值 30 | // root: tree root position in the tree ndoe array 31 | // start: interval start 32 | // end: interval end 33 | void Build(int *arr, int root, int start, int end) { 34 | // base case 1: no element 35 | if (start >= end) { 36 | return; 37 | } 38 | 39 | // base case 2: only one element 40 | if (start + 1 == end) { 41 | g_seg_tree[root].val = arr[start]; 42 | return; 43 | } 44 | 45 | // iterative case 46 | int mid = start + (end - start) / 2; 47 | // build left child root 48 | Build(arr, 2*root+1, start, mid); 49 | // build right child root 50 | Build(arr, 2*root+2, mid, end); 51 | g_seg_tree[root].val = min(g_seg_tree[2*root+1].val, g_seg_tree[2*root+2].val); 52 | } 53 | 54 | // only in query, we can return a value, because we won't make any change to the tree 55 | int Query(int root, int start, int end, int query_start, int query_end) { 56 | if (query_start <= start && query_end >= end) { 57 | // 查询区间 包含 当前区间 58 | return g_seg_tree[root].val; 59 | } else if (query_start >= end || query_end <= start) { 60 | // 查询区间 和 当前区间 没有交集 61 | return INT_MAX; 62 | } 63 | 64 | int mid = start + (end - start) / 2; 65 | return min(Query(root*2+1, start, mid, query_start, query_end), 66 | Query(root*2+2, mid, end, query_start, query_end)); 67 | } 68 | 69 | // interval is left closed, right open 70 | void UpdateAt(int root, int start, int end, int pos, int new_val) { 71 | if (start >= end) { 72 | return; 73 | } 74 | 75 | if (start + 1 == end && start == pos) { 76 | g_seg_tree[root].val = new_val; 77 | return; 78 | } 79 | 80 | int mid = start + (end - start) / 2; 81 | if (pos < mid) { 82 | // left child root 83 | UpdateAt(2*root+1, start, mid, pos, new_val); 84 | } else { 85 | // right child root 86 | UpdateAt(2*root+2, mid, end, pos, new_val); 87 | } 88 | // update self using left and right 89 | g_seg_tree[root].val = min(g_seg_tree[2*root+1].val, g_seg_tree[2*root+2].val); 90 | } 91 | 92 | /****************************************************************************/ 93 | /* 94 | * Advanced and super simple implementation of Segment Tree 95 | * for int type 96 | * */ 97 | const int kMaxArrSize = 1e5; // 1e5 = 100,000 98 | int n; 99 | int t[2 * kMaxArrSize]; 100 | 101 | void build() { 102 | for (int i = n - 1; i > 0; --i) { 103 | t[i] = t[i>>1] + t[i>>1 | 1]; // i>>1 = i / 2, i>>1 | 1 = i / 2 + 1; 104 | } 105 | } 106 | 107 | void modify(int p, int val) { 108 | for (t[p+=n] = val; p > 1; p >>= 1) { 109 | // if p if left child, p^1 is right child, and vice versa 110 | t[p>>1] = t[p] + t[p^1]; 111 | } 112 | } 113 | 114 | // [l, r) 115 | int query(int l, int r) { 116 | int res = 0; 117 | for (l += n, r += n; l < r; l>>=1, r>>=1) { 118 | // 左边有落单的 119 | if (l&1) res += t[l++]; 120 | // 右边有落单的 121 | if (r&1) res += t[--r]; 122 | // 如果都没有落单的,则交由父节点去求和 123 | } 124 | 125 | return res; 126 | } 127 | 128 | 129 | int main() { 130 | int a[] = {2, 5, 1, 4, 9, 3}; 131 | //int n = sizeof(a) / sizeof(*a); 132 | int n = 6; 133 | Build(a, 0, 0, n); 134 | cout << Query(0, 0, n, 0, 3) << endl; 135 | UpdateAt(0, 0, n, 2, 10); 136 | cout << Query(0, 0, n, 0, 3) << endl; 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /advanced/SuffixArray.cpp: -------------------------------------------------------------------------------- 1 | // refer to /Dropbox/**面试/ACM/后缀数组***.pdf 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int kMaxN = 200001; // 8 | // wss is cnt[i] 9 | int wa[kMaxN], wb[kMaxN], wv[kMaxN], cnt[kMaxN]; 10 | 11 | int cmp(int *r, int a, int b, int offset) { 12 | return r[a] == r[b] && r[a + offset] == r[b + offset]; 13 | } 14 | 15 | void da(int *r, int *sa, int n, int m) { 16 | int i = 0, gap = 0, p = 0; 17 | int *x = wa, *y = wb, *tmp = NULL; 18 | 19 | // cnting sort on array r 20 | for (i = 0; i < m; ++i) cnt[i] = 0; 21 | for (i = 0; i < n; ++i) cnt[x[i] = r[i]]++; // record the count of element r[i] 22 | for (i = 1; i < m; ++i) cnt[i] += cnt[i-1]; // add up 23 | for (i = n - 1; i >= 0; --i) sa[--cnt[x[i]]] = i; 24 | 25 | // 若干次基数排序 26 | for (gap = 1, p = 1; p < n; gap <<= 1, m = p) { 27 | // 对第二关键字基数排序, 结果放在y数组中 28 | for (p = 0, i = n - gap; i < n; ++i) y[p++] = i; 29 | for (i = 0; i < n; ++i) if (sa[i] >= gap) y[p++] = sa[i] - gap; 30 | 31 | // 对第一关键字基数排序, 复用y数组 32 | for (i = 0; i < n; ++i) wv[i] = x[y[i]]; 33 | // cnting sort 34 | for (i = 0; i < m; ++i) cnt[i] = 0; 35 | for (i = 0; i < n; ++i) cnt[wv[i]]++; // record the count 36 | for (i = 1; i < m; ++i) cnt[i] += cnt[i - 1]; // add up 37 | for (i = n - 1; i >= 0; --i) sa[--cnt[wv[i]]] = y[i]; 38 | 39 | // 40 | for (tmp = x, x = y, y = tmp, p = 1, x[sa[0]] = 0, i = 1; i < n; ++i) 41 | x[sa[i]] = (cmp(y, sa[i - 1], sa[i], gap) != 0) ? p - 1 : p++; 42 | } 43 | 44 | return; 45 | } 46 | 47 | int ranking[kMaxN], height[kMaxN]; 48 | void BuildHeight(int *r, int *sa, int n) { 49 | int i, j, k = 0; 50 | for (i = 1; i <= n; ++i) ranking[sa[i]] = i; 51 | 52 | for (i = 0; i < n; height[ranking[i++]] = k) 53 | for (k != 0 ? k-- : 0, j = sa[ranking[i] - 1]; r[i + k] == r[j + k]; ++k) 54 | ; 55 | } 56 | 57 | int main() { 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /advanced/Trie.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int kMaxNum = 26; // adjust according to real cases 6 | struct TrieNode { 7 | TrieNode* next[kMaxNum]; 8 | int cnt; 9 | }; 10 | 11 | TrieNode g_mem[1000000]; // using in ACM for saving time 12 | int g_alloc_idx = 0; // current available memory 13 | 14 | // ************************************************************ 15 | TrieNode* CreateNode() { 16 | TrieNode *new_node = &g_mem[g_alloc_idx++]; 17 | for (int i = 0; i < kMaxNum; ++i) { 18 | new_node->next[i] = NULL; 19 | } 20 | return new_node; 21 | } 22 | 23 | void Insert(TrieNode *root, string str) { 24 | if (root == NULL) { 25 | return; 26 | } 27 | 28 | TrieNode *cursor = root; 29 | int i = 0; 30 | while (str[i] != '\0') { 31 | int c = str[i] - 'a'; 32 | if (cursor->next[c] == NULL) { 33 | cursor->next[c] = CreateNode(); 34 | } 35 | 36 | // update node data 37 | cursor->next[c]->cnt++; 38 | cursor = cursor->next[c]; 39 | i++; 40 | } 41 | } 42 | 43 | int Search(TrieNode *root, string str) { 44 | if (root == NULL) { 45 | return 0; 46 | } 47 | 48 | TrieNode *cursor = root; 49 | int i = 0; 50 | while (str[i] != '\0') { 51 | int c = str[i] - 'a'; 52 | if (cursor->next[c] == NULL) { 53 | // search ends 54 | return 0; 55 | } else { 56 | // go further 57 | cursor = cursor->next[c]; 58 | i++; 59 | } 60 | } 61 | 62 | return cursor->cnt; // return the node cnt that hold the last char of the query stirng 63 | } 64 | 65 | int main() { 66 | TrieNode *root = CreateNode(); 67 | Insert(root, "inn"); 68 | Insert(root, "int"); 69 | Insert(root, "at"); 70 | Insert(root, "age"); 71 | Insert(root, "adv"); 72 | Insert(root, "ant"); 73 | cout << Search(root, "a") << endl; 74 | cout << Search(root, "in") << endl; 75 | cout << Search(root, "ad") << endl; 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /advanced/UnionFind.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int MAX_NUM = 10; 6 | 7 | int cnt = 0; 8 | int id[MAX_NUM]; 9 | 10 | void init(){ 11 | cnt = MAX_NUM; 12 | for(int i = 0; i < MAX_NUM; ++i){ 13 | id[i] = i; 14 | } 15 | } 16 | 17 | int find(int p){ 18 | return id[p]; 19 | } 20 | 21 | bool connected(int p, int q){ 22 | return find(p) == find(q); 23 | } 24 | 25 | void myunion(int p, int q){ 26 | int pid = find(p); 27 | int qid = find(q); 28 | if(pid == qid) return ; 29 | for(int i = 0; i < MAX_NUM; ++i){ 30 | if(id[i] == pid) 31 | id[i] = qid; 32 | } 33 | cnt--; 34 | } 35 | 36 | int main() 37 | { 38 | ifstream in; 39 | in.open("uf.txt"); 40 | cin.rdbuf(in.rdbuf()); 41 | 42 | int a, b; 43 | init(); 44 | while(cin>>a>>b){ 45 | if(connected(a, b)) continue; 46 | myunion(a, b); 47 | } 48 | cout< 2 | using namespace std; 3 | 4 | class M{ 5 | public: 6 | M(){ 7 | cout<<"1" <