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);
 	}

 }
Exemplo n.º 2
0
   //! <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;
   }