Chinaunix首页 | 论坛 | 博客
  • 博客访问: 148215
  • 博文数量: 56
  • 博客积分: 245
  • 博客等级: 二等列兵
  • 技术积分: 520
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-08 14:43
个人简介

慢慢来

文章分类

全部博文(56)

文章存档

2017年(5)

2016年(2)

2015年(6)

2014年(28)

2013年(5)

2012年(10)

我的朋友

分类: C/C++

2014-08-07 17:21:25

**转载请注明**

第三章在讨论一些定义和理论,一些标记方法:
f(n) = O(g(n))  is like  a<=b
f(n) = Ω(g(n))  is like a>=b
f(n) = Θ(g(n))  is like  a=b
f(n) = o(g(n))  is like  a
f(n) = ω(g(n))  is like  a>b

======================= 分割线 ===========================
继续算法

求最大字数组:(假如你有一次机会去买去卖股票,图形如下,找出能获得最大收益的卖出买入点)



原理:
    提到这个算法实际是为了验证divide-and-conquer这种概念。
    在price中引入了change。(即变化)
    随便在change数组之间找个中间点,假如为: mid。
   假设数组为 [low, high]。 最大子数组结果为 [i, j](i>=low, j<=high)。那么我们找到mid后,只有三种情况:
    1. i , j 都小于 mid 
    2. i , j 都大于 mid
   3. i 小于 mid,j 大于 mid

    对于1,2,那就接着取新的mid。对于3,从mid向左,以mid为准,取连续的最大的子数组;以mid+1为准,向右取最大,加一起。

    比较1,2,3.


点击(此处)折叠或打开

  1. #include <iostream>

  2. using namespace std;

  3. // I think if there is a struct stores these int[3] will be the best.
  4. // That would be: max subarr of left point ; right point ; max calculated values
  5. // Anyway, this worked

  6. int* FIND_MAX_CROSSING_SUBARRAY( int*, int, int, int ); // left point ; right point ; max value
  7. int* FIND_MAXIMUM_SUBARRAY( int*, int, int ); // as well

  8. int main(){
  9.     int a[] = {13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7};
  10.     int* subarr = new int[3];

  11.     subarr = FIND_MAXIMUM_SUBARRAY(a, 0, sizeof(a)/sizeof(int)-1);

  12.     for (int i = subarr[0]; i <= subarr[1]; i++){
  13.         cout << a[i] << endl;
  14.     }
  15.     return 0;
  16. }

  17. int* FIND_MAX_CROSSING_SUBARRAY( int* array, int low, int mid, int high ){
  18.     int max_left = INT_MIN, max_right = INT_MIN;
  19.     int max_left_p = mid, max_right_p = mid+1;
  20.     for( int i = mid, max = 0; i >= low; i-- ){
  21.         max += array[i];
  22.         if ( max_left < max ){
  23.             max_left_p = i;
  24.             max_left = max;
  25.         }
  26.     }

  27.     for( int i = mid+1, max = 0; i <= high; i++){
  28.         max += array[i];
  29.         if ( max_right < max ){
  30.             max_right_p = i;
  31.             max_right = max;
  32.         }
  33.     }

  34.     int* max_subarr = new int[3];
  35.     max_subarr[0] = max_left_p;
  36.     max_subarr[1] = max_right_p;
  37.     max_subarr[2] = max_left + max_right;

  38.     return max_subarr; // left point ; right point ; max value
  39. }

  40. int* FIND_MAXIMUM_SUBARRAY( int* array, int low, int high ){
  41.     if ( low == high ){ // only one item in array then return this as the biggest
  42.         int* max_subarr = new int[3];
  43.         max_subarr[0] = low;
  44.         max_subarr[1] = high;
  45.         max_subarr[2] = array[low];
  46.         return max_subarr;
  47.     } else{
  48.         int mid = (high-low)/2+low; // set mid point as floor of half high and low
  49.         int *left = new int[3], *right = new int[3], *cross = new int[3];

  50.         left = FIND_MAXIMUM_SUBARRAY(array, low, mid);
  51.         right = FIND_MAXIMUM_SUBARRAY(array, mid+1, high);
  52.         cross = FIND_MAX_CROSSING_SUBARRAY(array, low, mid, high);

  53.         if ( left[2] > right[2] && left[2] > cross[2] ){
  54.             return left;
  55.         } else if ( right[2] > left[2] && right[2] > cross[2] ){
  56.             return right;
  57.         } else {
  58.             return cross;
  59.         }
  60.     }
  61. }

运行结果:



空间复杂度: // 跟归并一样 
    O(n)

时间复杂度:
    O(nlgn)


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