```
public class Solution {
public int minCost(int[][] costs) {
if (costs == null || costs.length == 0) return 0;
int n = costs.length;
int nColors = costs[0].length;
int[][] cached = new int[n][nColors];
return worker(n, nColors, 0, -1,costs, cached);
}
public int worker(int n, int nColors, int index, int preColor, int[][]costs, int[][] cached) {
if (index == n) return 0;
int cost = Integer.MAX_VALUE;
for (int i = 0; i < nColors; i++) {
if (i != preColor) {
if (cached[index][i] == 0) {
cached[index][i] = costs[index][i] + worker(n, nColors, index+1, i, costs, cached);
}
cost = Math.min(cost, cached[index][i]);
}
}
return cost;
}
}
```