zoukankan      html  css  js  c++  java
  • 算法练习——和最接近于零的子数组

    问题描述:

    求对于长度为N的数组A,求子数组的和接0的子数组,要求时间复杂度O(NlogN) 

    (1) 求出所有的sum[i]  sum[i]表示A的前 项和
    (2) 对sum[-1,0,...,N-1]排序,然后计算sum相邻元素的差的绝对值,最小记为 min1   
    (3) min1 : 在A中任意取两个相邻子数组的和,求两者差的最小值。(相当于 i——j和的最小值)
    (4) min2 : A的前k个元素的和的绝对值的最小值(为sum[0,1....n-1]中的最小值)
    (5) min1和min2更小者,即为所求。

     1 public class SumIsZero {
     2     public static int SumMinIsZero(int[] a, int length){
     3         int[] sum = new int[length];
     4         //同时定义sum[-1] = 0;
     5         //sum[-1] = 0;
     6         //求前n项的和并且存在sum数组中,在从里面求出绝对值最小的数
     7         sum[0] = a[0];
     8         int i;
     9         //求出所以的sum[i]
    10         for (i = 1; i < length; i++) {
    11             sum[i] = sum[i-1]+a[i];
    12         }
    13         int min2 = Math.abs(sum[0]);
    14         for (i = 0; i < sum.length; i++) {
    15             if (Math.abs(sum[i]) < min2) 
    16                 min2 = Math.abs(sum[i]);
    17         }
    18         
    19         //同时对数组sum做排序
    20         quickSort(sum, 0, length-1);
    21         
    22         //求sum排序之后的相邻元素的最小值min1
    23         int min1 = Math.abs(sum[0]-sum[1]);
    24         for (int j = 2; j < sum.length; j++) {
    25             if (Math.abs(sum[j] - sum[j-1]) <min1) 
    26                 min1 = Math.abs(sum[j] - sum[j-1]);
    27         }
    28         return (min1 > min2 ? min2:min1);
    29     }

    快速查找(保证满足题目的时间复杂度)

     1 public static void quickSort(int[] a, int low,int high){
     2         int i,j;
     3         int temp;
     4         
     5         i=low;
     6         j=high;
     7         temp=a[low];                //取第一个元素为标准数据元素
     8         //下面的对左边和右边的扫描定位反复进行,直到左边的下标i大于或者等于右边元素的下标为止
     9         while(i<j){
    10             //在数组的右边扫描,如果数大于哨兵,则不改变位置,否则将j上的元素马上移动到i位置,
    11             //并且马上扫描左边
    12             while( i < j&& a[j]>=temp) j--;
    13             if (i<j) {
    14                 a[i]=a[j];
    15                 i++;
    16             }
    17             
    18             //在数组的左边扫描,如果数小于哨兵,则不改变位置,否则将左边i处的位置交换到
    19             //右边j处的位置,并且转回扫描右边
    20             while( i < j&& a[i] < temp) i++;
    21             if (i<j) {
    22                 a[j]=a[i];
    23                 j--;
    24             }
    25         }
    26         
    27         a[i]=temp;
    28         
    29         //对左边的子集合做递归查询
    30         if (low<i) {
    31             quickSort(a, low, i-1);
    32         }
    33         //对右边的子集合做递归查询
    34         if (i<high) {
    35             quickSort(a, j+1, high);
    36         }
    37     }

    但是以上算法只是简单的得到了最接近零的子数组的和,并没有得到所有的子数组。

  • 相关阅读:
    Timed Code
    jQuery的deferred对象详解
    ASP.NET MVC 使用Redis共享Session
    .NET垃圾回收(GC)原理
    强命名程序集,签名,延迟签名
    CLR 关于强命名程序集 .
    .NET程序集强命名删除与再签名技术 源代码剖析
    应用Strong Name保存.NET应用程序集
    使用强命名程序集防范篡改
    1.浅谈CLR
  • 原文地址:https://www.cnblogs.com/xiaxj/p/7245469.html
Copyright © 2011-2022 走看看