数组组合问题

  1. 求一个数组序列的所有连续子序列(时间复杂度为O(N3))
private static void continSubString(int[] nums) {
		List<List> result = new ArrayList<>();
		for (int i = 0; i < nums.length; i++) {
			for (int j = i; j < nums.length; j++) {
				List<Integer> thisSubString = new ArrayList<>();
				for (int k = i; k <= j; k++) {
					thisSubString.add(nums[k]);
				}
				result.add(thisSubString);
			}
		}
		System.out.println(Arrays.asList(result));
	}
  1. 求一个数组中n个数的所有组合
public static void main(String[] args) {
		int[] nums = new int[] {-2, 11, -4};
		System.out.println(Arrays.asList(combine(nums, 2)));
	}
	
	private static List<List> combine(int[] nums, int count) {
		List<List> res = new ArrayList<>();
		List<Integer> thisCombine = new ArrayList<>();
		combineHelper(nums, count, 0, thisCombine, res);
		return res;
	}
	
	private static void combineHelper(int[] nums, int count, int pos, List<Integer> thisCombine, List<List> res) {
		if (count == 0) {
			ArrayList<Integer> tmp = new ArrayList<>(thisCombine);
			res.add(tmp);
			return;
		}
		for (int i = pos; i < nums.length; i++) {
			thisCombine.add(nums[i]);
			combineHelper(nums, count - 1, i + 1, thisCombine, res);
			thisCombine.remove(thisCombine.size() - 1);
		}
	}
  1. 求一个数组的所有组合
    将上面的程序main函数体改为
		for (int i = 1; i <= nums.length; i++) {
			System.out.println(Arrays.asList(combine(nums, i)));
		}

4.1. 分治法求最大连续子序列和(O(NlogN))(为方便起见,若序列所有数均为负数,则最大子序列和为0,下同)

public static void main(String[] args) {
		int[] nums = new int[] {4, -3, 5, -2, -1, 2, 6, -2};
		System.out.println(maxSubSum(nums));
	}
	
	public static int maxSubSum(int[] nums) {
		return maxSumRec(nums, 0, nums.length - 1);
	}
	
	private static int maxSumRec(int[] nums, int left, int right) {
		if (left >= right) {
			if (nums[left] > 0) {
				return nums[left];
			}
			else {
				return 0;
			}
		}
		
		int center = (left + right) / 2;
		int maxLeftSum = maxSumRec(nums, left, center);
		int maxRightSum = maxSumRec(nums, center + 1, right);
		
		int maxLeftBorderSum = 0;
		int leftBorderSum = 0;
		for (int i = center; i >= left; i--) {
			leftBorderSum += nums[i];
			if (leftBorderSum > maxLeftBorderSum) {
				maxLeftBorderSum = leftBorderSum;
			}
		}
		
		int maxRightBorderSum = 0;
		int rightBorderSum = 0;
		for (int i = center + 1; i <= right; i++) {
			rightBorderSum += nums[i];
			if (rightBorderSum > maxRightBorderSum) {
				maxRightBorderSum = rightBorderSum;
			}
		}
		
		return Math.max(Math.max(maxLeftSum, maxRightSum), maxLeftBorderSum + maxRightBorderSum);
	}

4.2. 线性时间求最大连续子序列和(O(N))

public static int maxSubSum(int[] nums) {
		int maxSum = 0; 
		int thisSum = 0;
		for (int j = 0; j < nums.length; j++) {
			thisSum += nums[j];
			if (thisSum > maxSum) {
				maxSum = thisSum;
			} else if (thisSum < 0) {
				thisSum = 0;
			}
		}
		return maxSum;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值