字节跳动实习 多次出现的高频算法题

Descrpiton:

给定一个数组,比如说

int[] a = {1, 4, -5, 9, 8, 3, -6};
int[] b = {1, -2, 3, 10, -4, 7, 2, -5};

求出其最大子数组和(最大子数组必须是连续的)
其最大子数组为 9, 8, 3 ,所以和为 20
b 的和是 18

Solution:

本题可以用动态规划来做,俗称 dp

dp最重要的就是状态转移方程(这一步和前一步的关系):

dp[i] = max(dp[i - 1] + array[i], array[i])

这里dp代表的是前 i 个元素最大子数组和(必须使用到第i - 1个元素,如果 dp[i-1] + array[i] > array[i])
理由是:因为子数组是要连续的,所以如果要用之前的值,必须使用到第i - 1个元素。所以对于任意dp[i],它必须使用到第 i 个元素为了下一步使用。比如 i = 2,则 dp = 1 + 4 + -5 = 0. 这也就是为什么这里要用max来记录临时最大值,而不是直接返回 dp[array.length + 1]

综合代码如下:

private int largesub(int[] a) {
        //dp 第一步分配一个数组空间
        int[] dp = new int[a.length + 1];
        //dp 第二步初始化初始位置的值
        dp[0] = 0;
        int max = 0;
        //dp 第三步写出状态转移方程  dp[i] = max( dp[i - 1] + arr[i], arr[i] )
        //这里dp代表的是前 i 个元素最大子数组和(必须使用到第i - 1个元素,如果 dp[i-1] + array[i] > array[i])
        //理由是:因为子数组是要连续的,所以如果要用之前的值,必须使用到第i - 1个元素。
        //如果之前元素之和小于0,则使用第 i 个元素。使用max记录最大值(通常dp返回dp最后一个元素即可,这里不太一样)

        for(int i = 0; i < a.length; ++i) {
            dp[i + 1] = Math.max(dp[i] + a[i], a[i]);
            max = dp[i + 1] > max ? dp[i + 1] : max;
        }

        return max;
    }

你可能感兴趣的:(LeetCode)