House robber

Pick values from a row so that no two picks are next to each other, and the total is as large as possible.

Time O(n)Space O(n)Code C++, Python and C#
Watch it animatedStep through it, with the running line highlighted. Free with an account.

The idea

dp[i] is the best total using the first i houses. For house i there are two choices: skip it and keep dp[i-1], or take it and add its value to dp[i-2].

Code

int rob(const vector<int>& a) {
    vector<int> dp(a.size() + 1, 0);
    dp[1] = a[0];
    for (int i = 2; i <= (int)a.size(); i++)
        dp[i] = max(dp[i - 1], dp[i - 2] + a[i - 1]);
    return dp[a.size()];
}
def rob(a: list[int]) -> int:
    dp = [0] * (len(a) + 1)
    dp[1] = a[0]
    for i in range(2, len(a) + 1):
        dp[i] = max(dp[i - 1], dp[i - 2] + a[i - 1])
    return dp[len(a)]
public static int Rob(int[] a) {
    var dp = new int[a.Length + 1];
    dp[1] = a[0];
    for (int i = 2; i <= a.Length; i++)
        dp[i] = Math.Max(dp[i - 1], dp[i - 2] + a[i - 1]);
    return dp[a.Length];
}

Tips

In the .NET library

Math.Max makes the take-or-skip choice one expression. As with climbing stairs, two variables can replace the array.