未排序正数数组中累加和为给定值的最长子数组长度

import java.util.*;
//未排序正数数组中累加和为给定值的最长子数组长度
public class MaxSubArrLen{
	
	//方法一:排序后选择O(N*N)
	public static int GetMaxSub(int[]arr,int k)
	{
		if(arr==null||k<=0||arr.length==0)
		{
			return 0;
		}
		Arrays.sort(arr);
		if(arr[0]>k)
		{
			return 0;
		}
		int sum=0;
		int len=0; //子数组的长度
		for(int i=0;i<arr.length;i++)
		{
             sum+=arr[i];
             if(sum==k)
             {
               len=Math.max(len,i+1);
             }else if(sum>k)
             {
                 for(int j=0;j<i;j++)
                 {
                 	if(sum-arr[j]==k)
                 	{
                 		len=i-j;
                 		break;
                 	}
                 }
             }

		}
		return len;
	}
	//方法二:指正的移动,时间复杂度为O(N)
   public static int GetMaxSub2(int[] arr, int k) {
		if (arr == null || arr.length == 0 || k <= 0) {
			return 0;
		}
		int left = 0;
		int right = 0;
		int sum = arr[0];
		int len = 0;
		while (right < arr.length) {
			if (sum == k) {
				len = Math.max(len, right - left + 1);
				sum -= arr[left++];
			} else if (sum < k) {
				right++;
				if (right == arr.length) {
					break;
				}
				sum += arr[right];
			} else {
				sum -= arr[left++];
			}
		}
		return len;
	}


	public static void main(String[]args)
	{
	   int[]arr={1,2,1,1,1};
	   int k=3;
	   System.out.println(GetMaxSub(arr,k));
        System.out.println(GetMaxSub2(arr,k));
	}
}


题目描述 给定一个长度为n的正整数数组numbers,求长度至少为l的子数组的几何平均最大。 解题思路 几何平均公式为:$(a_1 \times a_2 \times ... \times a_n) ^ {\frac{1}{n}}$。 假设从第i个数开始的长度为j的子数组的几何平均为$x_{i,j}$,则有: $$ x_{i,j} = (numbers_i \times numbers_{i+1} \times ... \times numbers_{i+j-1}) ^ {\frac{1}{j}} $$ 那么,对于每一个i,我们需要找到长度至少为l的最大几何平均的子数组,即: $$ max_{i} \{max_{j \geq l}\{x_{i,j}\}\} $$ 也就是说,我们需要遍历数组,对于每一个i,以该数为起点,计算从该点开始长度至少为l的所有子数组的几何平均,然后取最大。 为了简化计算,我们可以将每个数先取log,于是几何平均公式就变成了算术平均公式: $$ \left(\frac{log\ a_1 + log\ a_2 + ... + log\ a_n}{n}\right) ^ {e} $$ 其中$e$为常数$e = 2.71828...$,这样我们就可以用前缀和来快速计算子数组的$log$总和。 具体实现时,我们可以用二分答案来减少计算量。对于每一个i,我们可以遍历从该点开始的所有子数组(假设总共有$m$个),计算出每个子数组的$log$总和,然后排序,取前$n$个,算出其算术平均,与二分答案的进行比较,确定二分答案的方向。 时间复杂度为$O(n \log n)$ (其中排序的时间复杂度为$O(m \log m)$,但$m$是$O(n^2)$级别的,故时间复杂度不变) 代码实现 以下是Python代码实现:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值