int MedianOfMergedArray(std::vector<int> &first_arr, std::vector<int> &second_arr, int size){ /* arr1=[1, 3, 4, 6], arr2=[5, 7, 8, 9] => [1, 3, 4, 5, 6, 7, 8, 9]=> => med1=(3+4)/2=3; med2=(7+8)/2=7 if(med1 < med2) => arr1[3, 4, 6]; arr2[5, 7, 8]=> med1=4; med2=7 med1<med2) => arr1[4, 6]; arr2[5, 7] => size=2=> (5+6)/2 */ if(size == 0){ return -1; } else if(size == 1){ return (first_arr[0] + second_arr[0])/2; } else if(size == 2){ return (std::max(first_arr[0], second_arr[0]) + std::min(first_arr[1], second_arr[1]))/2; } int med1 = median(first_arr); int med2 = median(second_arr); if(med1 == med2){ return med1; } if(med1 < med2){ // then we can view arr1[med1,...] and arr2[...,med2] if(size % 2 == 0){ std::vector<int> new_first(first_arr.begin(),first_arr.begin()+size/2-1); return MedianOfMergedArray(new_first, second_arr, size/2+1); } else{ std::vector<int> new_first(first_arr.begin(),first_arr.begin()+size/2); return MedianOfMergedArray(new_first, second_arr, size/2); } } if(size % 2 == 0){ std::vector<int> new_second(second_arr.begin(), second_arr.begin()+size/2-1); return MedianOfMergedArray(new_second, first_arr, size/2+1); } else{ std::vector<int> new_second(second_arr.begin(), second_arr.begin()+size/2); return MedianOfMergedArray(new_second, first_arr, size/2+1); } }
//! <b>Effects</b>: Moves the first n nodes starting at p to the beginning of the list. //! //! <b>Returns</b>: A pair containing the new first and last node of the list or //! if there has been any movement, a null pair if n leads to no movement. //! //! <b>Throws</b>: Nothing. //! //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions. static std::pair<node_ptr, node_ptr> move_first_n_forward(node_ptr p, std::size_t n) { std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0)); //Null shift, or count() == 0 or 1, nothing to do if(!n || !p || !NodeTraits::get_next(p)) return ret; node_ptr first = p; //Iterate until p is found to know where the current last node is. //If the shift count is less than the size of the list, we can also obtain //the position of the new last node after the shift. node_ptr old_last(first), next_to_it, new_last(p); std::size_t distance = 1; while(!!(next_to_it = node_traits::get_next(old_last))){ if(distance++ > n) new_last = node_traits::get_next(new_last); old_last = next_to_it; } //If the shift was bigger or equal than the size, obtain the equivalent //forward shifts and find the new last node. if(distance <= n){ //Now find the equivalent forward shifts. //Shortcut the shift with the modulo of the size of the list std::size_t new_before_last_pos = (distance - (n % distance))% distance; //If the shift is a multiple of the size there is nothing to do if(!new_before_last_pos) return ret; for( new_last = p ; --new_before_last_pos ; new_last = node_traits::get_next(new_last)){ //empty } } //Get the first new node node_ptr new_first(node_traits::get_next(new_last)); //Now put the old beginning after the old end NodeTraits::set_next(old_last, p); NodeTraits::set_next(new_last, node_ptr(0)); ret.first = new_first; ret.second = new_last; return ret; }