必记算法
1 public static void insertSort(int[] a){ 2 for(int j=1;j<a.length;j++){ 3 int key=a[j]; 4 int i=j-1; 5 while(i>=0&&key<a[i]){ 6 a[i+1]=a[i]; 7 i--; 8 } 9 a[i+1]=key; 10 } 11 } 12 13 public static void merge(int[] a,int p,int q,int r){ 14 int n1=q-p+1; 15 int n2=r-q; 16 17 int[]left=new int[n1+1]; 18 int[]right=new int[n2+1]; 19 20 for(int i=0,j=p;i<n1;i++,j++){ 21 left[i]=a[j]; 22 } 23 for(int i=0,j=q+1;i<n2;i++,j++){ 24 right[i]=a[j]; 25 } 26 left[n1]=Integer.MAX_VALUE; 27 right[n2]=Integer.MAX_VALUE; 28 29 int i=0,j=0; 30 for(int k=p;k<=r;k++){ 31 if(left[i]<=right[j]){ 32 a[k]=left[i++]; 33 } 34 else{ 35 a[k]=right[j++]; 36 } 37 } 38 } 39 40 public static void mergeSort(int[]a ,int p,int r){ 41 if(p<r){ 42 int q=(p+r)/2; 43 mergeSort(a,p,q); 44 mergeSort(a,q+1,r); 45 merge(a,p,q,r); 46 } 47 } 48 public static void bubbleSort(int[]a){ 49 for(int i=1;i<a.length;i++){ 50 for(int j=0;j<a.length-i;j++){ 51 if(a[j]>a[j+1]){ 52 int tmp=a[j]; 53 a[j]=a[j+1]; 54 a[j+1]=tmp; 55 } 56 } 57 } 58 } 59 60 public static int partition(int[]a,int p,int r){ 61 int key=a[r]; 62 int i=p; 63 for(int j=p;j<r;j++){ 64 if(a[j]<=key){ 65 //a[i] <--> a[j] 66 int tmp=a[i]; 67 a[i]=a[j]; 68 a[j]=tmp; 69 70 i++; 71 } 72 } 73 74 //a[i] <--> a[r] 75 int tmp=a[i]; 76 a[i]=a[r]; 77 a[r]=tmp; 78 79 return i; 80 } 81 public static void quickSort(int[]a,int p,int r){ 82 if(p<r){ 83 int q=partition(a,p,r); 84 //int q=hoarePartition(a,p,r); 85 quickSort(a,p,q-1); 86 quickSort(a,q+1,r); 87 } 88 } 89 public static void insertSortRecursion(int[]a,int p){ 90 if(p>0){ 91 insertSortRecursion(a,p-1); 92 93 int i=p-1; 94 int key=a[p]; 95 while(i>=0&&key<a[i]){ 96 a[i+1]=a[i]; 97 i--; 98 } 99 a[i+1]=key; 100 } 101 } 102 103 public static void insertSortUsingBinarySearch(int[]a){ 104 for(int j=1;j<a.length;j++){ 105 int key=a[j]; 106 int i=Search.binarySearch(a,0,j-1, key); 107 if(i<0) 108 i=-i-1; 109 for(int k=j-1;k>=i;k--) 110 a[k+1]=a[k]; 111 a[i]=key; 112 } 113 } 114 115 public static void selectSort(int[]a){ 116 for(int i=0;i<a.length-1;i++){ 117 int k=i; 118 for(int j=k+1;j<a.length;j++){ 119 if(a[j]<a[k]) 120 k=j; 121 } 122 if(k!=i){ 123 int tmp=a[k]; 124 a[k]=a[i]; 125 a[i]=tmp; 126 } 127 } 128 } 129 130 131 132 133 public static int binarySearch(int[] a,int low,int high,int key){ 134 if(low>high) 135 throw new IllegalArgumentException("low > high"); 136 137 while(low<=high){ 138 int mid=(low+high)/2; 139 if(key<a[mid]) 140 high=mid-1; 141 else if(key>a[mid]) 142 low=mid+1; 143 else 144 return mid; 145 } 146 return -(low+1); 147 } 148 149 public static int binarySearch(int[]a,int key){ 150 return binarySearch(a,0,a.length-1,key); 151 } 152 153 public static int binarySearchRecursion(int[] a,int low,int high,int key){ 154 if(low<=high){ 155 int mid=(low+high)/2; 156 if(key<a[mid]) 157 return binarySearchRecursion(a,low,mid-1,key); 158 else if(key>a[mid]) 159 return binarySearchRecursion(a,mid+1,high,key); 160 else 161 return mid; 162 } 163 else{ 164 return -(low+1); 165 } 166 } 167 168 public static int binarySearchRecursion(int[]a,int key){ 169 return binarySearchRecursion(a,0,a.length-1,key); 170 } 171 172 173 174 175 176 177 public static int bs_min2(int[] a, int key) { 178 /*假设n>=0, a[-1]<key&&a[n]>=key(但是程序并不访问这两个假想的元素)*/ 179 int low=-1, high=a.length; 180 while(low+1!=high){ 181 /*invariant: a[low]<key && a[high]>=key && low<high */ 182 int mid=(low+high)/2; 183 if(a[mid]<key) 184 low=mid; 185 else 186 high=mid; 187 } 188 /*assert low+1=high && a[low]<key && a[high]>=key*/ 189 int p=high; 190 if(p>=a.length||a[p]!=key) 191 //p=-1; 192 p=-(high+1); 193 return p; 194 } 195 public static int bs_max2(int[]a,int key){ 196 int l=-1,r=a.length; 197 while(l+1!=r){ 198 int m=(l+r)/2; 199 if(a[m]<=key) 200 l=m; 201 else 202 r=m; 203 } 204 int p=l; 205 if(p<=-1||a[p]!=key) 206 p=-(l+1+1); 207 return p; 208 } 209 210 public int countInversions(int[]a,int p,int r){ 211 int inversion=0; 212 if(p<r){ 213 int q=(p+r)/2; 214 inversion+=countInversions(a, p, q); 215 inversion+=countInversions(a, q+1, r); 216 inversion+=mergeInversions(a, p, q, r); 217 } 218 return inversion; 219 } 220 221 public int mergeInversions(int[]a,int p,int q,int r){ 222 int n1=q-p+1; 223 int n2=r-q; 224 int[]left=new int[n1+1]; 225 int[]right=new int[n2+1]; 226 227 for(int i=0,j=p;j<=q;i++,j++){ 228 left[i]=a[j]; 229 } 230 left[n1]=Integer.MAX_VALUE; 231 232 for(int i=0,j=q+1;j<=r;i++,j++){ 233 right[i]=a[j]; 234 } 235 right[n2]=Integer.MAX_VALUE; 236 237 int inversion=0; 238 int i=0,j=0; 239 for(int k=p;k<=r;k++){ 240 if(right[j]<left[i]){ 241 inversion+=n1-i; 242 /*for(int iter=i;iter<n1;iter++){ 243 inversionPairs.add(new Pair(left[iter],right[j])); 244 }*/ 245 246 a[k]=right[j++]; 247 } 248 else{ 249 a[k]=left[i++]; 250 } 251 } 252 return inversion; 253 } 254 255 public static int randomizedSelect(int[]a,int p,int r,int i){ 256 if(p==r){ 257 return a[p]; 258 } 259 int q=randomizedPartition(a,p,r); 260 int k=q-p+1; 261 if(i==k){ 262 return a[q]; 263 } 264 else if(i<k){ 265 return randomizedSelect(a,p,q-1,i); 266 } 267 else{ 268 return randomizedSelect(a,q+1,r,i-k); 269 } 270 } 271 272 public static int randomizedSelect2(int[]a,int p,int r,int i){ 273 int q=randomizedPartition(a,p,r); 274 int k=q-p+1; 275 while(i!=k){ 276 if(i < k){ 277 r=q-1; 278 } 279 else{//i > k 280 p=q+1; 281 i-=k; 282 } 283 q=randomizedPartition(a,p,r); 284 k=q-p+1; 285 } 286 return a[q]; 287 } 288 289 int maxSum(int a[],int n){ 290 int max=INT_MIN; 291 for(int i=0;i<n;i++){ 292 for(int j=i;j<n;j++){ 293 int s=0; 294 for(int k=i;k<=j;k++){ 295 s+=a[k]; 296 } 297 if(s>max) 298 max=s; 299 } 300 } 301 return max; 302 } 303 304 int maxSum2(int a[],int n){ 305 int max=INT_MIN; 306 for(int i=0;i<n;i++){ 307 int s=0; 308 for(int j=i;j<n;j++){ 309 s+=a[j]; 310 if(s>max) 311 max=s; 312 } 313 } 314 return max; 315 } 316 317 int maxSum3(int a[],int n){ 318 int*s=new int[n]; 319 s[0]=a[0]; 320 for(int i=1;i<n;i++){ 321 s[i]=s[i-1]+a[i]; 322 } 323 int max=INT_MIN; 324 for(int i=0;i<n;i++){ 325 if(s[i]>max) 326 max=s[i]; 327 } 328 for(int i=1;i<n;i++){ 329 for(int j=i;j<n;j++){ 330 int sum=s[j]-s[i-1]; 331 if(sum>max) 332 max=sum; 333 } 334 } 335 delete []s; 336 return max; 337 } 338 339 int _max(int a,int b){ 340 return a>b?a:b; 341 } 342 343 int _max(int a,int b,int c){ 344 int m=a; 345 if(b>m) 346 m=b; 347 if(c>m) 348 m=c; 349 return m; 350 } 351 352 int _maxSum4(int a[],int l,int r){ 353 if(l>r) 354 return 0; 355 if(l==r) 356 return a[l]; 357 int m=(l+r)/2; 358 int lmax=INT_MIN,lsum=0; 359 for(int i=m;i>=l;i--){ 360 lsum+=a[i]; 361 if(lsum>lmax) 362 lmax=lsum; 363 } 364 int rmax=INT_MIN,rsum=0; 365 for(int i=m+1;i<=r;i++){ 366 rsum+=a[i]; 367 if(rsum>rmax) 368 rmax=rsum; 369 } 370 371 return _max(lmax+rmax,_maxSum4(a,l,m),_maxSum4(a,m+1,r)); 372 } 373 int maxSum4(int a[],int n){ 374 return _maxSum4(a,0,n-1); 375 } 376 377 int maxSum5(int a[],int n){ 378 /前i个元素中,最大子段和要么在前i-1个元素中(存储在maxsofar), 379 要么其结束为止为i(存储在maxendinghere)*/ 380 int maxsofar=INT_MIN,maxendinghere=0; 381 for(int i=0;i<n;i++) { 382 maxendinghere=_max(maxendinghere+a[i],a[i]); 383 maxsofar=_max(maxsofar,maxendinghere); 384 } 385 return maxsofar; 386 } 387 388 public static int LISLength(int[]a){ 389 int[]lens=new int[a.length]; 390 for(int i=0;i<a.length;i++){ 391 lens[i]=1; 392 for(int j=0;j<i;j++){ 393 if(a[i]>=a[j]&&lens[j]+1>lens[i]){ 394 lens[i]=lens[j]+1; 395 } 396 } 397 } 398 399 int max=Integer.MIN_VALUE; 400 for(int i=0;i<a.length;i++){ 401 if(lens[i]>max) 402 max=lens[i]; 403 } 404 return max; 405 } 406 407 //若返回值为x,则a[x]>=val>a[x-1] 408 private static int find(int[]a,int high,int val){ 409 int low=0; 410 while(low<=high){ 411 int mid=(low+high)/2; 412 if(val<a[mid]) 413 high=mid-1; 414 else if(val>a[mid]) 415 low=mid+1; 416 else 417 return mid; 418 } 419 return low; 420 } 421 422 public static int LISLength2(int[]a){ 423 int[]lastElems=new int[a.length+1]; 424 lastElems[0]=Integer.MIN_VALUE; 425 lastElems[1]=a[0]; 426 427 int maxLen=1; 428 for(int i=1;i<a.length;i++){ 429 int j=find(lastElems,maxLen, a[i]); 430 lastElems[j]=a[i]; 431 if(j>maxLen) 432 maxLen=j; 433 } 434 return maxLen; 435 } 436 437 438 439 440 441 public static int[] countingSort(int[] a, int k) { 442 int[] b = new int[a.length]; 443 int[] c = new int[k]; 444 445 for (int i = 0; i < a.length; i++) { 446 c[a[i]]++; 447 } 448 449 for (int i = 1; i < c.length; i++) { 450 c[i] += c[i - 1]; 451 } 452 453 for (int i = a.length - 1; i >= 0; i--) { 454 b[--c[a[i]]] = a[i]; 455 } 456 457 return b; 458 } 459 460 #include <stdlib.h> 461 int bigrand(){ 462 return RAND_MAX*rand()+rand(); 463 } 464 465 int rand(int l,int u){ 466 return l+bigrand()%(u-l+1); 467 } 468 void genknuth(int m,int n) 469 { 470 for(int i=0;i<n;i++){ 471 int r=bigrand(); 472 if(r%(n-i)<m){ 473 cout<<i<<' '; 474 m--; 475 } 476 } 477 cout<<endl; 478 } 479 480 void gensets(int m,int n){ 481 set<int> s; 482 while(s.size()<m){ 483 s.insert(bigrand()%n); 484 } 485 for(set<int>::iterator it=s.begin();it!=s.end();++it){ 486 cout<<*it<<' '; 487 } 488 cout<<endl; 489 } 490 491 void genshuf(int m,int n){ 492 int* a=new int[n]; 493 for(int i=0;i<n;i++) 494 a[i]=i; 495 for(int i=0;i<m;i++){ 496 int j=rand(i,n-1); 497 int t=a[i];a[i]=a[j];a[j]=t; 498 } 499 sort(a,a+m); 500 for(int i=0;i<m;i++) 501 cout<<a[i]<<' '; 502 cout<<endl; 503 504 delete []a; 505 } 506 题目:有两个长为n的非递减数组A和B,把B接在A的后面变成长为2n的数组C。设计算法求C的中位数(第n小数)。 507 思路:O(n)的算法很容易找到,关键是用二分的思想设计logn算法。这题关键是用好a和b数组中脚标和为定值的元素的大小关系。 508 直观想法是:如果中位数在数组a中,那么若a[m]<b[n-m-2],此时比a[m]小的数最多只有n-2个,即a[m]不可能为第n小数,偏小更新左界;若a[m]> b [n-m-1],此时比a[m]小的数至少有n个,a[m]不可能为第n小数,偏大更新右界;若a[m]介于b[n-m-2]与b [n-m-1]则a[m]恰好为第n小数。 中位数在数组b中的情况类似。 509 510 int findNthNumber(int a[], int b[], int n){ 511 int l = 0, r = n -1; 512 int m; 513 while(l <= r){ 514 m = (l + r) / 2; 515 if(m <= n - 2 && a[m] < b[n - m -2]){ 516 //此时比a[m]小的数最多只有n-2个,即a[m]不可能为第n小数,偏小更新左界 517 l = m + 1; 518 } 519 else if (a[m] < b [n - m - 1]){ 520 //此时比a[m]小的数恰好有n-1个,a[m]就是第n小数,返回 521 return a[m]; 522 } 523 else r = m - 1;//此时比a[m]小的数至少有n个,即a[m]不可能为第n小数,偏大更新右界 524 } 525 //中位数在b数组中的情况,和上面类似 526 l = 0, r = n -1; 527 while(l <= r){ 528 m = (l + r) / 2; 529 if(m <= n - 2 && b[m] < a[n - m -2]){ 530 l = m + 1; 531 } 532 else if (b[m] < a [n - m - 1]){ 533 return b[m]; 534 } 535 else r = m - 1; 536 } 537 } 538 539 也可以取a[m]与b[n-m-2]中较大的一个,然后与a[m+1]和b[n-m-1]作比较,简化后的代码如下 540 int findNthNumber(int a[], int b[], int n){ 541 int l = 0, r = n -1; 542 int m, tmp; 543 while(l <= r){ 544 m = (l + r) / 2; 545 tmp = (a[m] < b [n - m - 2] ? b[n - m - 2] : a[m]); 546 //tmp取a[m]与b[n-m-2]中较大的一个,然后与a[m+1]和b[n-m-1]作比较 547 if(tmp > b [n - m - 1]){ 548 r = m - 1; 549 } 550 else if(tmp > a [m + 1]){ 551 l = m + 1; 552 } 553 else return tmp; 554 } 555 } 556 //输入一个字符串,找出其中出现的相同的且长度最长的字符串。eg:input:banana output:ana. 557 int comlen(const char* str1,const char* str2){ 558 assert((str1!=0)&&(str2!=0)); 559 int len=0; 560 while(*str1!='\0'&&*str2!='\0'&&*str1++==*str2++){ 561 len++; 562 } 563 return len; 564 } 565 566 bool less(char* str1,char* str2){ 567 return strcmp(str1,str2)<=0; 568 } 569 570 void longestRepeatedSubstring(char* string){ 571 int n=strlen(string); 572 char** a=new char*[n]; 573 for(int i=0;i<n;i++){ 574 a[i]=string+i; 575 } 576 sort(a,a+n,::less); 577 578 int maxlen=-1,maxi; 579 for(int i=0;i<n-1;i++){ 580 int len=comlen(a[i],a[i+1]); 581 if(len>maxlen){ 582 maxlen=len; 583 maxi=i; 584 } 585 } 586 587 printf("%.*s\n",maxlen,a[maxi]); 588 589 delete []a; 590 }
待续。。。

浙公网安备 33010602011771号