连续子数组的和的最大值、最小值以及和的绝对值的最大值、最小值

连续子数组的和的最大值、最小值以及和的绝对值的最大值、最小值

标签: 子数组最小和绝对值最大和     http://blog.csdn.net/zuijinhaoma8/article/details/45290145
527人阅读 评论(1) 收藏 举报
分类:


  1. #include <iostream>  
  2. #include <vector>  
  3. #include <algorithm>  
  4. using namespace std;  
  5.   
  6. //求子数组的最小和  
  7. //利用的是dp的思想,依次遍历数组中的每个元素,把他们相加,如果加起来大于0,则  
  8. //把当前元素之和清为0,否则则和最小和比较,更新最小和,最后得到必是子数组的最小和  
  9. //时间复杂度:o(n) 空间复杂度:o(1)  
  10. int minSum(vector<int> &num)  
  11. {  
  12.     int min_sum = 0, sum = 0;  
  13.   
  14.     for(int i=0; i<num.size(); i++)  
  15.     {  
  16.         sum += num[i];  
  17.         if(sum > 0) sum = 0;  
  18.         if(sum < min_sum)  
  19.             min_sum = sum;  
  20.     }  
  21.     if(min_sum == 0) //数组中只有正数  
  22.     {  
  23.         min_sum = num[0];  
  24.         for(int i=1; i<num.size(); i++)  
  25.         {  
  26.             if(num[i]<min_sum)  
  27.                 min_sum = num[i];  
  28.         }  
  29.     }  
  30.     return min_sum;  
  31. }  
  32.   
  33. //求子数组的最大和  
  34. //利用的是dp的思想,依次遍历数组中的每个元素,把他们相加,如果加起来小于0,则  
  35. //把当前元素之和清为0,否则则和最大和比较,更新最大和,最后得到必是子数组的最大和  
  36. //时间复杂度:o(n)  
  37. int maxSum(vector<int> &num)  
  38. {  
  39.     int max_sum = 0, sum = 0;  
  40.   
  41.     for(int i=0; i<num.size(); i++)  
  42.     {  
  43.         sum += num[i];  
  44.         if(sum < 0) sum = 0;  
  45.         if(sum > max_sum)  
  46.             max_sum = sum;  
  47.     }  
  48.     if(max_sum == 0) //数组中只有负数  
  49.     {  
  50.         max_sum = num[0];  
  51.         for(int i=1; i<num.size(); i++)  
  52.         {  
  53.             if(num[i]>max_sum)  
  54.                 max_sum = num[i];  
  55.         }  
  56.     }  
  57.     return max_sum;  
  58. }  
  59.   
  60. //求子数组的和的绝对值的最小值  
  61. //暴力穷举法  
  62. //时间复杂度:o(n^2) 空间复杂度:o(1)  
  63. int minAbsSum1(vector<int> &num)  
  64. {  
  65.     int min_abs_sum = INT_MAX;  
  66.     for(int i=0; i<num.size(); i++)  
  67.     {  
  68.         int cur_sum = 0;  
  69.         for(int j=i; j<num.size(); j++)  
  70.         {  
  71.             cur_sum += num[j];  
  72.             if(abs(cur_sum) < min_abs_sum)  
  73.                 min_abs_sum = abs(cur_sum);  
  74.         }  
  75.     }  
  76.     return min_abs_sum;  
  77. }  
  78.   
  79. //求子数组的和的绝对值的最小值  
  80. //先计算所有sum[0-j] 0<= j <n,然后对sum[0-j]的数组进行排序,那么对于任何i,j段的和等于:sum[i-j]= sum[0-j] - sum[0-i];  
  81. //设置数组sum用来存储子数组0-j的和  
  82. //因为已经对sum进行了排序,排序后只需要找到sum[z]-sum[z-1],sum[z]  (0<=z<sum.size())的绝对值的最小值即可。z为排序后的索引  
  83. //如果是sum[z]情形,z为排序后的索引,则minAbs = abs(sum[0-i])  
  84. //如果是sum[z]-sum[z-1]情形,则minAbs = abs(sum[i]-sum[j])  
  85. //时间复杂度:o(nlogn) 空间复杂度:o(n)  
  86. int minAbsSum2(vector<int> &num)  
  87. {  
  88.     if(num.size()==0) return 0;  
  89.     if(num.size()==1) return abs(num[0]);  
  90.     int min_abs_sum;  
  91.     vector<int> sum;  
  92.     int cur_sum = 0;  
  93.     for(int i=0; i<num.size(); i++)  
  94.     {  
  95.         cur_sum += num[i];  
  96.         if(cur_sum == 0)  
  97.             return 0;  
  98.         sum.push_back(cur_sum);  
  99.     }  
  100.     sort(sum.begin(), sum.end());  
  101.   
  102.     min_abs_sum = abs(sum[0]);  
  103.     for(int i=0; i<sum.size()-1; i++)  
  104.     {  
  105.         int temp1 = abs(sum[i+1]);  
  106.         int temp2 = abs(sum[i+1]-sum[i]);  
  107.         cur_sum = (temp1<temp2)?temp1:temp2;  
  108.         if(cur_sum == 0)  
  109.             return 0;  
  110.         if(cur_sum<min_abs_sum)  
  111.             min_abs_sum = cur_sum;  
  112.     }  
  113.     return min_abs_sum;  
  114. }  
  115.   
  116. //求子数组的和的绝对值的最da值  
  117. //暴力穷举法  
  118. //时间复杂度:o(n^2) 空间复杂度:o(1)  
  119. int maxAbsSum1(vector<int> &num)  
  120. {  
  121.     int max_abs_sum = 0;  
  122.     for(int i=0; i<num.size(); i++)  
  123.     {  
  124.         int cur_sum = 0;  
  125.         for(int j=i; j<num.size(); j++)  
  126.         {  
  127.             cur_sum += num[j];  
  128.             if(abs(cur_sum) > max_abs_sum)  
  129.                 max_abs_sum = abs(cur_sum);  
  130.         }  
  131.     }  
  132.     return max_abs_sum;  
  133. }  
  134.   
  135. //求子数组的和的绝对值的最大值  
  136. //先计算所有sum[0-j] 0<= j <n,然后对sum[0-j]的数组进行排序,那么对于任何i,j段的和等于:sum[i-j]= sum[0-j] - sum[0-i];  
  137. //设置数组sum用来存储子数组0-j的和  
  138. //因为已经对sum进行了排序,排序后只需要找到sum[sum.size()-1]-sum[0],sum[z]  (0<=z<sum.size())的绝对值的最大值即可。z为排序后的索引  
  139. //如果是sum[z]情形,z为排序后的索引,则maxAbs = abs(sum[0-i])  
  140. //如果是sum[sum.size()-1]-sum[0]情形,则maxAbs = abs(sum[i]-sum[j])  
  141. //时间复杂度:o(nlogn) 空间复杂度:o(n)  
  142. int maxAbsSum2(vector<int> &num)  
  143. {  
  144.     if(num.size()==0) return 0;  
  145.     if(num.size()==1) return abs(num[0]);  
  146.     int max_abs_sum;  
  147.     vector<int> sum;  
  148.     int cur_sum = 0;  
  149.     for(int i=0; i<num.size(); i++)  
  150.     {  
  151.         cur_sum += num[i];  
  152.         if(cur_sum == 0)  
  153.             return 0;  
  154.         sum.push_back(cur_sum);  
  155.     }  
  156.     sort(sum.begin(), sum.end());  
  157.     max_abs_sum = abs(sum[sum.size()-1]-sum[0]);  
  158.     for(int i=0; i<sum.size(); i++)  
  159.     {  
  160.         cur_sum = abs(sum[i]);  
  161.         if(cur_sum>max_abs_sum)  
  162.             max_abs_sum = cur_sum;  
  163.     }  
  164.     return max_abs_sum;  
  165. }  
  166.   
  167. int main()  
  168. {  
  169.     int n;  
  170.     while(cin>>n)  
  171.     {  
  172.         vector<int> num;  
  173.         int number;  
  174.         for(int i=0; i<n; i++)  
  175.         {  
  176.             cin>>number;  
  177.             num.push_back(number);  
  178.         }  
  179.         cout<<"minSum = "<<minSum(num)<<endl;  
  180.         cout<<"maxSum = "<<maxSum(num)<<endl;  
  181.         cout<<"minAbsSum1 = "<<minAbsSum1(num)<<endl;  
  182.         cout<<"minAbsSum2 = "<<minAbsSum2(num)<<endl;  
  183.         cout<<"maxAbsSum1 = "<<maxAbsSum1(num)<<endl;  
  184.         cout<<"maxAbsSum2 = "<<maxAbsSum2(num)<<endl;  
  185.         cout<<"------------------------------------"<<endl;  
  186.     }  
  187.     return 0;  
  188. }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值