276. Paint Fence

题目:
There is a fence with n posts, each post can be painted with one of the k colors.java

You have to paint all the posts such that no more than two adjacent fence posts have the same color.post

Return the total number of ways you can paint the fence.spa

Note:
n and k are non-negative integers.code

解答:
这道题其实跟house rob很相似,用dp作的时候在function部分很容易写错,当取跟前面不同的颜色时,这一轮一共有除了前面这个颜色的k-1个颜色能够选;当取跟前面同样的颜色的时候,这一轮只有一种状况能够选,且:前一轮不能取跟前前一轮同样的颜色,不然这三个post的颜色就都相同了,不符合题中说的最多两个相邻的post颜色相同。代码以下:it

public class Solution {
    //State: f[i][j] is total number of ways we can paint the fence;
    //Function: f[i][0] = f[i - 1][0] * k - 1 + f[i - 1][1] * (k - 1)
    //          f[i][1] = f[i - 1][0] + f[i - 1][1]
    //Initialize: f[0][0] = k, f[0][1] = k; f[1][0] = k * (k - 1), f[1][1] = k;
    //Result: f[n - 1][0] + f[n - 1][1];
    public int numWays(int n, int k) {
        if (n == 0 || k == 0) return 0;
        if (n == 1) return k;
        int[][] f = new int[n][2];
        //Initialize
        f[0][1] = f[1][1] = k;
        f[0][0] = k;
        f[1][0] = k * (k - 1);
        //f[i][0]表示跟前面不同颜色,f[i][1]表示跟前面同样颜色
        for (int i = 2; i < n; i++) {
            //跟前面不同颜色的话,在这轮有k - 1种可能性
            f[i][0] = f[i - 1][0] * (k - 1) + f[i - 1][1] * (k - 1);
            //跟前面同样颜色的话,在这轮有1种可能性,且前一轮不能与前前一轮同样颜色
            f[i][1] = f[i - 1][0];
        }
        
        return f[n - 1][0] + f[n - 1][1];
    }
}

由于这个dp的解法里,咱们只用到变量i - 1和i,因此咱们能够进定步把空间复杂度降为o(1):io

//Save space to O(1) because it only cares about i - 1 and i
    public int numWays(int n, int k) {
        if (n == 0 || k == 0) return 0;
        if (n == 1) return k;
        int diff = k * (k - 1);
        int same = k;
        for (int i = 2; i < n; i++) {
            int tmp = diff;
            diff = (diff + same) * (k - 1);
            same = tmp;
        }
        return same + diff;
    }
相关文章
相关标签/搜索