Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1002703
  • 博文数量: 150
  • 博客积分: 3017
  • 博客等级: 少校
  • 技术积分: 3829
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 14:40
个人简介

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: Python/Ruby

2012-06-18 18:58:02

合并两个有序数组。
 
题目2年前面baidu的时候问的,看起来很简单,写起来还是容易错。当年太菜,写的少。现在写出来不错也不容易。第二种解法写了很久,实际是相当复杂的。
 
最简单的当然是新建一个数组然后一个个往里面放。
其复杂度为a+b
 
 
Solution 1 :这个二分法插入是不额外开辟空间的,逐个插入。
复杂度大致为 b*log(a)
 
Solution 2 :从B中用二分法选取插入的连续元素块,直接插入数个元素
初始值x=0;
b[x]应插入到a[cur]的位置(二分法得到位置),那么直到b中最后一个小于a[cur+1]的元素b[y](二分法得到y)共y-x个,都应依次插入到当前a[cur]的位置,从a[cur+1]开始剩余的元素,都应向后移动y-x个位置。
完成后则b[y]之前的元素都已经插入。然后x置为y+1,重复以上操作,直至所有b中元素都插入a中
二分查找时对位置加以限制,从上轮插入结束的位置开始,这样又降低了部分复杂度
复杂度大致为log2(a)+log2(b). 最差时比较和移动了a+b次

 

点击(此处)折叠或打开

  1. my @a = (1,3,5,7);
  2. my @b = (1,2,4,6,8);

  3. my $start = 0;
  4. my $end = @a -1 ;
  5. for my $t (@b){
  6.     print "Tracking $t \n";
  7.     my $cur;
  8.     #binary search
  9.     do{
  10.         $cur = int(($start+$end)/2);
  11.         $end = $cur if($t<$a[$cur]);
  12.         $start = $cur if($t>$a[$cur]);
  13.         if($t == $a[$cur]){
  14.             $end = $cur +1;
  15.             $start = $cur;
  16.         }
  17.     }
  18.     while($end-$start >1);
  19.     
  20.     #assign the proper postion
  21.     $cur = $end;
  22.     
  23.     #if the value is larger than the last element in current array, then append thelement to the last;
  24.     if($t>$a[$end]){
  25.         $cur = $end+1;
  26.     }
  27.     #move elements after current postion with distance 1
  28.     for(my $i = @a-1; $i >= $cur; $i--){
  29.         $a[$i+1] = $a[$i];
  30.     }
  31.     $a[$cur] = $t;
  32.     $start = $cur;
  33.     $end = @a-1;
  34.     print ;

  35. }




点击(此处)折叠或打开

  1. #! /usr/bin/perl
  2. my @b = (2,4,6,8);
  3. my @a = (1,3,5,7);

  4. my $count = 0;

  5. sub getInsertPostion{
  6.     my ($in, $si, $ei, @queue) = @_;
  7.     if($in<$queue[$si]){
  8.         $count++;
  9.         return $si;
  10.     }
  11.     if($in>=$queue[$ei]){
  12.         $count++;
  13.         return @queue;
  14.     }
  15.     my $cur;
  16.     do{
  17.         $cur = int(($si+$ei)/2);
  18.         $ei = $cur if($in<=$queue[$cur]);
  19.         $si = $cur if($in>=$queue[$cur]);
  20.         $count ++;
  21.     }
  22.     while($ei-$si >1);
  23.     return $ei;
  24. }
  25. my $asi = 0;
  26. my $bsi = 0;
  27. my $aei = @a-1;
  28. my $bei = @b-1;
  29. my $size = @a+@b;
  30. while(@a<$size){
  31.     #while instert elements of b into a at the postion $cur
  32.     my $cur = getInsertPostion($b[$bsi], $asi, $aei, @a);
  33.     my $bei = getInsertPostion($a[$cur], $bsi, $bei, @b);


  34.     #the steps for @a to move forward
  35.     my $steps = () = ($bsi..$bei);
  36.     $steps --;
  37.     print "Step = $steps \n";

  38.     #move the elements of a after postion $cur by steps
  39.     for(0..(@a-$cur-1)){
  40.         $a[$aei-$_+$steps] = $a[$aei-$_];
  41.     }
  42.     print "after move foward by step $steps: @a \n";

  43.     #insert elements selected from b
  44.     #if steps is 0, it means that all left element of @b should append to @a.
  45.     $bei = @b if($steps == 0);

  46.     for($bsi..$bei-1){
  47.         print "fill a[$cur] with $b[$_]\n";
  48.         $a[$cur] = $b[$_];
  49.         $cur++;

  50.     }
  51.     print "@a \n";

  52.     #next round, select elements of b from the postion that ending this round
  53.     $bsi = $bei;
  54.     $bei = @b-1;    

  55.     #the next round will start from the postion after insert.
  56.     $asi = $cur+ $steps;
  57.     $aei = @a-1;
  58.     print "--------------------------------------\n";
  59. }

  60. print "@a \n";
  61. print "Compare executed for $count times\n";



阅读(5958) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~