算法与数据结构面试题(3)-求子数组的最大和

题目


输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
因此输出为该子数组的和18。


理解


说实在的刚开始拿到这个题目的时候,我是晕的。完全不知道解题思路在哪里。但是我想到了用动态规划,因为有点类似背包问题。只想到了这么多,后来参看前辈们的思想,有点豁然开朗的感觉。


前辈文章:http://blog.csdn.net/hackbuteer1/article/details/6694193


他的解题思路是这样的:


1.解题步骤分为:目前的子数组的和不能为负,因为为负再跟后面相加,肯定会减少后面的子数组的和。那么如果为负,就重置为0。记录下当前的下标,那么这样我们就抛弃了之前遍历的子数组,剩下来的问题就是解被剩下来的数组的最大值。以此类推,直到遍历到最后一个元素。

2.如果所有数都为负数,也就遍历完成后,最大值还是没有变化过,那么就要找到这个数组中最大的那个数,它就是最优解。


代码


package com.sprd.interview.algorithm;

/**
 * Copyright 2014 TJ SPREADTRUM TEST_AF All Right Reserved
 * 
 * @author: hui.qian Created on 2014年12月10日 下午8:16:43 Description:
 */
public class LargestChildArray {
	private int start;
	private int end;

	public int getSumOfLargestChildArray(int[] data) {
		if (data == null || data.length == 0) {
			throw new IllegalArgumentException("数组为空或者大小为0");
		}
		
		int largest = 0;
		int curLargest = 0;
		for (int i = 0; i < data.length; i++) {
			curLargest += data[i];
			if (curLargest < 0) {
				curLargest = 0;
				start = i;
			}

			if (curLargest > largest) {
				largest = curLargest;
				end = i;
			}

		}
		if (largest == 0) {
			// 任意一个排序算法后,得到最小的值
		}

		return largest;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] data = {1, -2, 3, 10, -4, 7, 2, -5};
		
		LargestChildArray childArray = new LargestChildArray();
		int max = childArray.getSumOfLargestChildArray(data);
		System.out.println("" + max);
		
	}

}



你可能感兴趣的:(算法与数据结构,LeetCode)