Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 1 | #include <iostream> |
| 2 | #include <vector> |
| 3 | #include <queue> |
| 4 | #include <cstdio> |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 5 | #include <map> |
| 6 | #include <stdio.h> |
| 7 | #include <cstring> |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 8 | |
| 9 | using namespace std; |
| 10 | //1 2 3 4 5 7 |
| 11 | int find_first_missing_number_helper(int *arr, int start, int end) |
| 12 | { |
| 13 | //base cases |
| 14 | int mid = (start + end) / 2; |
| 15 | int offset = mid - start; |
| 16 | |
| 17 | if (start >= end) return 0; |
| 18 | if ((arr[mid] + 1) != arr[mid+1]) return (arr[mid] + 1); |
| 19 | |
| 20 | if ((arr[start]+ offset) < arr[mid]) { |
| 21 | return find_first_missing_number_helper(arr, start, (mid)); |
| 22 | } else { |
| 23 | return find_first_missing_number_helper(arr, mid+1, end); |
| 24 | } |
| 25 | } |
| 26 | |
| 27 | int find_first_missing_number(int *arr, int size) |
| 28 | { |
| 29 | if ((size == 0) || (size == 1)) { return 0;} |
| 30 | |
| 31 | return find_first_missing_number_helper(arr, 0, size-1); |
| 32 | } |
| 33 | |
| 34 | int find_first_duplicate_number(int *arr, int start, int end) |
| 35 | { |
| 36 | //base case |
| 37 | int mid = (start+end)/2; |
| 38 | int offset = mid - start; |
| 39 | if (start >= end) {return -1;} //no duplication |
| 40 | if (arr[mid] == arr[mid+1]) {return arr[mid];} |
| 41 | |
| 42 | //recursion |
| 43 | if ((arr[start]+offset) < arr[mid]) { |
| 44 | return find_first_duplicate_number(arr, start, mid); |
| 45 | } else { |
| 46 | return find_first_duplicate_number(arr, mid+1, end); |
| 47 | } |
| 48 | } |
| 49 | |
| 50 | // 1 2 3 3 3 3 4 |
| 51 | // 1 3 |
| 52 | int find_first_target_number_in_sorted_array(int *arr, int start, int end, int target) |
| 53 | { |
| 54 | //base cases |
| 55 | int mid = (start + end) / 2; |
| 56 | if (start == end) { |
| 57 | if (arr[start] == target) { |
| 58 | return start; |
| 59 | } else { |
| 60 | return -1; |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | |
| 65 | if ((arr[mid] != arr[mid+1]) && (arr[mid+1] == target)) { |
| 66 | return mid+1; |
| 67 | } |
| 68 | |
| 69 | if (arr[mid] >= target) { |
| 70 | return find_first_target_number_in_sorted_array(arr, start, mid, target); |
| 71 | } else { |
| 72 | return find_first_target_number_in_sorted_array(arr, (mid+1), end, target); |
| 73 | } |
| 74 | } |
| 75 | |
| 76 | // 1 3 3 3 3 5 6 |
| 77 | // 1 3 |
| 78 | // 1 1 3 3 |
| 79 | int find_last_target_number_in_sorted_array(int *arr, int start, int end, int target) |
| 80 | { |
| 81 | //base cases |
| 82 | if (start == end) { |
| 83 | if (arr[start] == target) { |
| 84 | return start; |
| 85 | } else { |
| 86 | printf("last index for target %d is not found\n", target); |
| 87 | return -1; |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | int mid = (start + end) / 2; |
| 92 | |
| 93 | |
| 94 | if ((arr[mid] == target) && (arr[mid+1] != target)) { |
| 95 | return mid; //this is the last occurance of the target |
| 96 | } else { |
| 97 | if (arr[mid] > target) { |
| 98 | return find_last_target_number_in_sorted_array(arr, start, mid, target); |
| 99 | } else { |
| 100 | return find_last_target_number_in_sorted_array(arr, mid+1, end, target); |
| 101 | } |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | int find_target_number_occurance(int *arr, int start, int end, int target) |
| 106 | { |
| 107 | int first = find_first_target_number_in_sorted_array(arr, start, end, target); |
| 108 | if (first == -1) { |
| 109 | printf("target number %d is not found\n", target); |
| 110 | return -1; |
| 111 | } |
| 112 | |
| 113 | int last = find_last_target_number_in_sorted_array(arr, start, end, target); |
| 114 | if (last == -1) { |
| 115 | printf("invalid last index\n"); |
| 116 | return -1; |
| 117 | } |
| 118 | printf(" target %d occurs %d times\n", target, (last-first+1)); |
| 119 | return (last - first + 1); |
| 120 | } |
| 121 | |
| 122 | int climb_stairs_helper(int steps, int *buffer) |
| 123 | { |
| 124 | if (steps == 1) return 1; |
| 125 | if (steps == 2) return 2; |
| 126 | |
| 127 | if (buffer[steps] > 0) return buffer[steps]; //return value from the cache |
| 128 | |
| 129 | buffer[steps] = climb_stairs_helper((steps-1), buffer) + climb_stairs_helper((steps-2), buffer); |
| 130 | return buffer[steps]; |
| 131 | } |
| 132 | |
| 133 | int climb_stairs(int steps) |
| 134 | { |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 135 | int buffer[steps+1]; |
| 136 | |
| 137 | memset(buffer, 0x0, (steps+1)); |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 138 | int result = 0; |
| 139 | result = climb_stairs_helper(steps, buffer); |
| 140 | printf(" result for %d steps is %d\n", steps, result); |
| 141 | return result; |
| 142 | } |
| 143 | |
| 144 | int find_element_in_rotated_array(int *arr, int start, int end, int target) |
| 145 | { |
| 146 | // base cases |
| 147 | if (start == end) { |
| 148 | if (arr[start] != target) { |
| 149 | return (-1); //no element is found within the array |
| 150 | } else { |
| 151 | return start; |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | int mid = (start + end) / 2; |
| 156 | if (arr[mid] == target) return mid; |
| 157 | |
| 158 | if (arr[mid] == arr[start]) { |
| 159 | if (arr[mid] == arr[end]) { |
| 160 | //Need to search both left and right |
| 161 | int index = find_element_in_rotated_array(arr, start, (mid-1), target); |
| 162 | if (index >= 0) return index; |
| 163 | return find_element_in_rotated_array(arr, (mid+1), end, target); |
| 164 | } else { |
| 165 | return find_element_in_rotated_array(arr, (mid+1), end, target); |
| 166 | } |
| 167 | } else if (arr[mid] < arr[end]){ |
| 168 | if ((arr[mid] < target) && (target <= arr[end])) { |
| 169 | //target is on the right porition of the array (sorted) |
| 170 | return find_element_in_rotated_array(arr, (mid+1), end, target); |
| 171 | } else { |
| 172 | return find_element_in_rotated_array(arr, start, (mid-1), target); |
| 173 | } |
| 174 | } else if (arr[mid] > arr[start]) { |
| 175 | if ((arr[mid] > target) && (target >= arr[start])) { |
| 176 | //left side is sorted |
| 177 | return find_element_in_rotated_array(arr, start, (mid-1), target); |
| 178 | } else { |
| 179 | return find_element_in_rotated_array(arr, (mid+1), end, target); |
| 180 | } |
| 181 | } |
| 182 | return (-1); |
| 183 | } |
| 184 | |
| 185 | int find_number_in_rotated_array(int *arr, int size, int target) |
| 186 | { |
| 187 | int pos = find_element_in_rotated_array(arr, 0, (size-1), target); |
| 188 | printf(" target %d is in position %d\n", target, pos); |
| 189 | return pos; |
| 190 | } |
| 191 | |
| 192 | int count_rotations_helper(int *arr, int start, int end) |
| 193 | { |
| 194 | //base cases |
| 195 | if (start == end) return 0; //no rotation in the array |
| 196 | int mid = (start + end) / 2; |
| 197 | |
| 198 | if (arr[mid] > arr[mid+1]) { |
| 199 | return (mid+1); //mid+1 contains the smallest number in the array |
| 200 | } |
| 201 | |
| 202 | if (arr[mid] == arr[start]) { |
| 203 | if(arr[mid] < arr[end]) { |
| 204 | //the right side is sorted |
| 205 | return count_rotations_helper(arr, start, mid); |
| 206 | } else if (arr[mid] > arr[end]) { |
| 207 | return count_rotations_helper(arr, (mid+1), end); |
| 208 | } else { |
| 209 | // need to search both sides |
| 210 | int temp = count_rotations_helper(arr, start, mid); |
| 211 | if (temp > 0) return temp; |
| 212 | return count_rotations_helper(arr, (mid+1), end); |
| 213 | } |
| 214 | } else if (arr[mid] > arr[start]) { |
| 215 | return count_rotations_helper(arr, (mid+1), end); |
| 216 | } else { |
| 217 | return count_rotations_helper(arr, start, mid); |
| 218 | } |
| 219 | } |
| 220 | |
| 221 | int count_rotations_in_sorted_array(int *arr, int size) |
| 222 | { |
| 223 | int rotate_num = count_rotations_helper(arr, 0, (size-1)); |
| 224 | printf(" rotation is : %d\n", rotate_num); |
| 225 | } |
| 226 | |
| 227 | void print_subset_helper(vector< int > &subset) |
| 228 | { |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 229 | for (int i=0; i<subset.size(); i++) { |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 230 | printf(" %d ", i); |
| 231 | } |
| 232 | printf("\n"); |
| 233 | } |
| 234 | |
| 235 | void print_subsets_in_array(int *array, int size, vector<vector< int > > &subsets) |
| 236 | { |
| 237 | if (size == 0) return; //return an empty subset |
| 238 | |
| 239 | print_subsets_in_array(array, (size - 1), subsets); |
| 240 | |
| 241 | int element = array[size-1]; //get the number at size-1 |
| 242 | |
| 243 | for (int i=0; i<subsets.size(); i++) { |
| 244 | subsets[i].push_back(element); |
| 245 | print_subset_helper(subsets[i]); |
| 246 | } |
| 247 | |
| 248 | vector< int > temp; |
| 249 | temp.push_back(element); |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 250 | subsets.push_back(temp); |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 251 | printf(" %d\n", element); |
| 252 | } |
| 253 | |
| 254 | void print_powerset(int *arr, int size) |
| 255 | { |
| 256 | vector<vector< int > > subsets; |
| 257 | print_subsets_in_array(arr, size, subsets); |
| 258 | } |
| 259 | |
| 260 | void print_target_sum_pairs(int *arr, int size, int target_sum) |
| 261 | { |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 262 | map<int, int> complement; |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 263 | |
| 264 | for (int i=0; i<size; i++) { |
| 265 | int difference = target_sum - arr[i]; |
| 266 | if (complement[difference] == 0) { //no complement pair is found |
| 267 | complement[arr[i]]++; //increment the complement count |
| 268 | } else if (complement[difference] > 0) { |
| 269 | printf(" Pair: %d + %d = %d\n", arr[i], difference, target_sum); |
| 270 | complement[difference]--; |
| 271 | } |
| 272 | } |
| 273 | } |
| 274 | |
| 275 | void merge(int *arr, int *helper, int start, int mid, int end) |
| 276 | { |
| 277 | int left1 = start; |
| 278 | int left2 = mid; |
| 279 | int right1 = mid+1; |
| 280 | int right2 = end; |
| 281 | int current = left1; |
| 282 | |
| 283 | while ((left1 <= left2) && (right1 <= right2)) { |
| 284 | if (arr[left1] <= arr[right1]) { |
| 285 | helper[current] = arr[left1]; |
| 286 | left1++; |
| 287 | } else { |
| 288 | helper[current] = arr[right1]; |
| 289 | right1++; |
| 290 | } |
| 291 | current++; |
| 292 | } |
| 293 | |
| 294 | //copy the remaining elements |
| 295 | while (left1 <= left2) { |
| 296 | helper[current++] = arr[left1]; |
| 297 | left1++; |
| 298 | } |
| 299 | |
| 300 | while (right1 <= right2) { |
| 301 | helper[current++] = arr[right1]; |
| 302 | right1++; |
| 303 | } |
| 304 | |
| 305 | //copy the sorted items back to the original array; |
| 306 | for (int i=start; i<=end; i++) { |
| 307 | arr[i] = helper[i]; |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | void merge_sort_helper(int *arr, int *helper, int start, int end) |
| 312 | { |
| 313 | if (start < end) { |
| 314 | int mid = (start + end) / 2; |
| 315 | merge_sort_helper(arr, helper, start, mid); |
| 316 | merge_sort_helper(arr, helper, (mid+1), end); |
| 317 | merge(arr, helper, start, mid, end); |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | void merge_sort(int *arr, int size) |
| 322 | { |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 323 | int helper[size]; |
| 324 | |
| 325 | memset(helper, 0x0, size); |
| 326 | |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 327 | merge_sort_helper(arr, helper, 0, (size-1)); |
| 328 | |
| 329 | printf("Array after sorting: \n"); |
| 330 | for (int i=0; i<size; i++) { |
| 331 | printf(" %d", arr[i]); |
| 332 | } |
| 333 | printf("\n"); |
| 334 | } |
| 335 | |
| 336 | void test_merge_sort() |
| 337 | { |
| 338 | int arr1[2] = {2, 1}; |
| 339 | int arr2[3] = {3, 1, 2}; |
| 340 | int arr3[4] = {1, 2, 4, 3}; |
| 341 | int arr4[4] = {2, 1, 3, 4}; |
| 342 | int arr5[5] = {5, 2, 1, 3, 4}; |
| 343 | int arr6[5] = {5, 2, 1, 4, 3}; |
| 344 | int arr7[5] = {5, 4, 3, 2, 1}; |
| 345 | |
| 346 | merge_sort(arr1, 2); |
| 347 | merge_sort(arr2, 3); |
| 348 | merge_sort(arr3, 4); |
| 349 | merge_sort(arr4, 4); |
| 350 | merge_sort(arr5, 5); |
| 351 | merge_sort(arr6, 5); |
| 352 | merge_sort(arr7, 5); |
| 353 | } |
| 354 | void test_print_subset() |
| 355 | { |
| 356 | int arr1[1] = {1}; |
| 357 | int arr2[2] = {1, 2}; |
| 358 | int arr3[3] = {1, 2, 3}; |
| 359 | int arr4[4] = {1, 2, 2, 3}; |
| 360 | |
| 361 | print_powerset(arr1, 1); |
| 362 | printf("\n"); |
| 363 | print_powerset(arr2, 2); |
| 364 | printf("\n"); |
| 365 | print_powerset(arr3, 3); |
| 366 | printf("\n"); |
| 367 | print_powerset(arr4, 4); |
| 368 | printf("\n"); |
| 369 | } |
| 370 | |
| 371 | void test_print_target_sum_pairs() |
| 372 | { |
| 373 | int arr_1[1] = {1}; |
| 374 | int arr_2[2] = {1,2}; |
| 375 | int arr_3[3] = {1,3,5}; |
| 376 | int arr_4[4] = {1,2,0,4}; |
| 377 | int arr_5[5] = {1,2,0,4,1}; |
| 378 | int arr_6[8] = {7,1,6,2,5,3,2,6}; |
| 379 | int arr_7[7] = {7,2,2,7,3,6,9}; |
| 380 | |
| 381 | print_target_sum_pairs(arr_2, 1, 2); |
| 382 | print_target_sum_pairs(arr_2, 2, 3); |
| 383 | print_target_sum_pairs(arr_3, 3, 6); |
| 384 | print_target_sum_pairs(arr_4, 4, 4); |
| 385 | print_target_sum_pairs(arr_5, 5, 5); |
| 386 | print_target_sum_pairs(arr_6, 8, 8); |
| 387 | print_target_sum_pairs(arr_7, 8, 9); |
| 388 | } |
| 389 | |
| 390 | void test_count_rotations_in_sorted_array() |
| 391 | { |
| 392 | int arr1[2] = {3, 1}; |
| 393 | int arr2[3] = {3, 1, 2}; |
| 394 | int arr3[3] = {2, 3, 1}; |
| 395 | int arr4[4] = {3, 4, 1, 2}; |
| 396 | int arr5[4] = {2, 3, 4, 1}; |
| 397 | int arr6[5] = {3, 3, 3, 2, 3}; |
| 398 | int arr7[5] = {3, 2, 3, 3, 3}; |
| 399 | int arr8[5] = {3, 3, 3, 3, 3}; |
| 400 | |
| 401 | count_rotations_in_sorted_array(arr1, 2); |
| 402 | count_rotations_in_sorted_array(arr2, 3); |
| 403 | count_rotations_in_sorted_array(arr3, 3); |
| 404 | count_rotations_in_sorted_array(arr4, 4); |
| 405 | count_rotations_in_sorted_array(arr5, 4); |
| 406 | count_rotations_in_sorted_array(arr6, 5); |
| 407 | count_rotations_in_sorted_array(arr7, 5); |
| 408 | count_rotations_in_sorted_array(arr8, 5); |
| 409 | } |
| 410 | |
| 411 | void test_find_number_in_rotated_array() |
| 412 | { |
| 413 | int arr1[2] = {3, 1}; |
| 414 | int arr2[3] = {3, 1, 2}; |
| 415 | int arr3[3] = {2, 3, 1}; |
| 416 | int arr4[4] = {3, 4, 1, 2}; |
| 417 | int arr5[4] = {2, 3, 4, 1}; |
| 418 | int arr6[5] = {3, 3, 1, 2, 2}; |
| 419 | int arr7[5] = {3, 3, 1, 2, 3}; |
| 420 | |
| 421 | find_number_in_rotated_array(arr1, 2, 3); |
| 422 | find_number_in_rotated_array(arr1, 2, 1); |
| 423 | find_number_in_rotated_array(arr2, 3, 2); |
| 424 | find_number_in_rotated_array(arr3, 3, 2); |
| 425 | find_number_in_rotated_array(arr4, 4, 4); |
| 426 | find_number_in_rotated_array(arr5, 4, 1); |
| 427 | find_number_in_rotated_array(arr6, 5, 3); |
| 428 | find_number_in_rotated_array(arr7, 5, 2); |
| 429 | } |
| 430 | |
| 431 | void test_climb_stairs() |
| 432 | { |
| 433 | climb_stairs(1); |
| 434 | climb_stairs(2); |
| 435 | climb_stairs(3); |
| 436 | climb_stairs(4); |
| 437 | climb_stairs(5); |
| 438 | climb_stairs(6); |
| 439 | climb_stairs(7); |
| 440 | } |
| 441 | |
| 442 | void test_find_target_number_occurance() |
| 443 | { |
| 444 | // test cases: |
| 445 | int arr1[1] = {1}; |
| 446 | int arr2[2] = {1, 3}; |
| 447 | int arr3[3] = {1, 3, 3}; |
| 448 | int arr4[4] = {1, 3, 3, 3}; |
| 449 | int arr5[5] = {1, 2, 2, 2, 3}; |
| 450 | int arr6[6] = {2, 2, 2, 2, 2, 2}; |
| 451 | |
| 452 | |
| 453 | printf("%s\n", __func__); |
| 454 | |
| 455 | int rc_1 = find_target_number_occurance(arr1, 0, 0, 1); |
| 456 | int rc_2 = find_target_number_occurance(arr2, 0, 1, 1); |
| 457 | int rc_3 = find_target_number_occurance(arr3, 0, 2, 1); |
| 458 | int rc_4 = find_target_number_occurance(arr4, 0, 3, 3); |
| 459 | int rc_5 = find_target_number_occurance(arr5, 0, 4, 2); |
| 460 | int rc_6 = find_target_number_occurance(arr6, 0, 5, 2); |
| 461 | int rc_7 = find_target_number_occurance(arr6, 0, 5, 1); |
| 462 | } |
| 463 | |
| 464 | void test_first_missing_number() |
| 465 | { |
| 466 | int a1[1] = {1}; |
| 467 | int a2[2] = {2, 4}; |
| 468 | int a3[3] = {2, 3, 4}; |
| 469 | int a4[4] = {2, 3, 5, 6}; |
| 470 | int a5[4] = {2, 4, 5, 6}; |
| 471 | int a6[5] = {1, 2, 3, 5, 6}; |
| 472 | int a7[5] = {1, 2, 3, 4, 6}; |
| 473 | |
| 474 | printf("%s\n", __func__); |
| 475 | |
| 476 | int rc_1 = find_first_missing_number(a1, 1); |
| 477 | int rc_2 = find_first_missing_number(a2, 2); |
| 478 | int rc_3 = find_first_missing_number(a3, 3); |
| 479 | int rc_4 = find_first_missing_number(a4, 4); |
| 480 | int rc_5 = find_first_missing_number(a5, 4); |
| 481 | int rc_6 = find_first_missing_number(a6, 6); |
| 482 | int rc_7 = find_first_missing_number(a7, 7); |
| 483 | |
| 484 | printf("Results: %d %d %d %d %d %d %d\n", rc_1, rc_2, rc_3, rc_4, rc_5, rc_6, rc_7); |
| 485 | } |
| 486 | |
| 487 | int main() |
| 488 | { |
BobbyHo | 9b78cd4 | 2016-11-01 22:02:58 -0700 | [diff] [blame] | 489 | test_first_missing_number(); |
| 490 | test_find_target_number_occurance(); |
| 491 | test_climb_stairs(); |
| 492 | test_find_number_in_rotated_array(); |
| 493 | test_count_rotations_in_sorted_array(); |
| 494 | test_print_target_sum_pairs(); |
| 495 | test_print_subset(); |
Bobby Ho | efb037e | 2016-10-27 21:05:17 -0700 | [diff] [blame] | 496 | test_merge_sort(); |
| 497 | } |