最长的子阵列

时间:2016-09-19 01:12:38

标签: java arrays

任何人都可以提出以下问题的简单解决方案。

  

最长子阵列:查找最长连续子阵列的长度,其中子阵列中元素的总和小于或等于" k"。

输入为:arrayk

示例:

Array = {1,2,3}, k = 3

输出:

  

2

说明:

  

子数组:{1},{2},{3},{1,2},{2,3},{1,2,3}

     

{1,2} =>最大长度= 2; 1 + 2 = 3(< = k);

5 个答案:

答案 0 :(得分:1)

采用O(n)方法。在高级别:

有2个指针startendstart是子阵列的开头,end是结束(独占)。一个int sum来保持子阵列的总和。一个int len来保持子阵列len。

两者都设置为位置0.

  1. 继续移动end指针:

    while (end < arr.length && sum + arr[end] <= k) {
        sum += arr[end];
        end ++;
    }
    if ((end - start) > len ) {
      len = (end-start);
    }
    

    哪个会找到sum < k的最长子阵列,其中以start开头

  2. 移动start

    sum -= arr[start];
    start++;
    
  3. 返回1,直到end通过数组的最后一个元素

  4. 最后,您会找到最大长度(存储在len

    将一些边缘情况的处理留给您(例如,如果数组中的元素值为> k等等)

答案 1 :(得分:0)

最简单和天真的答案是遍历您的数组并找到从当前索引开始的最长子阵列。

int[] a = { 1,2,3,1,1,2,3,1,3 };
int k = 4;

int best_i = 0; // from index
int best_j = 0; // to index, so best length = j - i + 1
int best_sum = 0;

for (int i = 0; i < a.length; i++) { // starting index from beginning to end 
    int sum = 0;
    for (int j = i; j < a.length; j++) { // ending index from current to end
        sum += a[j];
        if (sum > k) break;
        if (j - i > best_j - best_i) { // best length found
            best_i = i;
            best_j = j;
            best_sum = sum;
        }
    }
}

System.out.println("best length = " + (best_j - best_i + 1) + " (indexes " + best_i + ".." + best_j + "), sum = " + best_sum);
// best length = 3 (indexes 3..5), sum = 4

答案 2 :(得分:0)

一种有效的方法是使用动态编程,以减少求和运算的次数。例如,如果你总和(1 + 2)= 3,你不想再求和(1 + 2 + 3)= 6,你只想求和(3 + 3)= 6(其中前三个已经是计算并保存到hashmap中)。在此解决方案中,hashmap表示从索引i到索引j的总和,格式为<i, <j, sum>>。因此,您可以从存储在内部hashmap中的索引i开始获得所有总和。请注意,您也可以使用2D数组而不是嵌套的hashmap结构,但对于非常大的数据,在初始化该数组时可能会出现内存不足异常。

    static int maxLength(int[] a, int k) {
        Map<Integer, Map<Integer, Long>> map = new HashMap<Integer, Map<Integer, Long>>();

        int maxLength = 0;
        for(int i = 0; i < a.length - 1; i++) {
            Map<Integer, Long> map2 = new HashMap<Integer, Long>();
            map2.put(i, (long)a[i]);
            map.put(i, map2);
            if(a[i] == k) {
                maxLength = 1;
            }
        }

        for(int l = 2; l <= a.length; l++) {
            long sum = 0;
            for(int i = 0; i <= a.length - l; i++) {
                int j = i + l - 1;
                Map<Integer, Long> map2 = map.get(i);
                sum = map2.get(j - 1) + a[j];
                map2.put(j, sum);

                if(sum <= k) {
                    if(l > maxLength) {
                        maxLength = l;
                    }
                }
            }
        }

        return maxLength;
    }

答案 3 :(得分:0)

Python 实现

时间复杂度O(n)

无需额外空间

def longest_sub_array_sum(input_array: list, k: int) -> int:
    longest_size = 0
    
    if input_array:
        i = 0
        j = 1
        longest_size = 0 if input_array[i] != k else 1
        current_sum = input_array[i]
        
        while j < len(input_array):
            if current_sum <= k:
                if j - i > longest_size:
                    longest_size = j - i
                current_sum += input_array[j]
                j += 1

            elif current_sum > k:
                current_sum -= input_array[i]
                i += 1
                
    return longest_size

答案 4 :(得分:-1)

这里我只使用for循环,但我怀疑这个解决方案的复杂性,是O(n)还是O(n2)。看起来像是一个for循环,但我不认为一些操作不是蛮力或两个for循环。

function maxLength(a,k){

Android.Runtime.JavaList<T>

}