有一个整数数组,例如。
{3,1,2,7,5,6}
可以一次向前移动数组中的每个元素,也可以根据该索引处的值跳转一些元素。例如,一个可以从3到1或3到7,然后一个可以从1到2或1到2(这里没有跳跃),然后一个可以去2到7或2到5,然后一个可以去7到5只有7的coz指数是3并且加7到3 = 10并且没有第十个元素。
我必须只计算从起始索引到达数组末尾的可能路径数。
我只能在指数时间内以递归和天真的方式进行。
有人请帮助。
答案 0 :(得分:2)
我的建议:使用动态编程。
如果这个关键词已经足够,并且您希望挑战能够自行找到可能的解决方案,请不要再阅读了!
这里是示例输入{3,1,2,7,5,6}
上可能的DP算法。调整一般问题是你的职责。
创建数组sol
长度为6,其中只有零。数组将保持多种方式。
sol[5] = 1;
for (i = 4; i>=0;i--) {
sol[i] = sol[i+1];
if (i+input[i] < 6 && input[i] != 1)
sol[i] += sol[i+input[i]];
}
return sol[0];
运行时O(n)
至于评论中暗示的有向图解决方案:
数组中的每个单元代表一个节点。从每个节点到可访问节点的定向边缘。基本上你可以通过查看节点上的outdegrees来更容易地计算方法的数量(因为没有定向循环)但是实际编程它是很多锅炉板。
调整递归解决方案
另一个解决方案是修剪。这基本上等同于DP算法。指数时间来自于您多次计算值的事实。例如,函数是recfunc(index)
。初始调用recFunc(0)
调用recFunc(1) and recFunc(3)
,依此类推。但是recFunc(3)
必然会再被称为some recFunc(x)
,这会导致重复的递归计算。要修剪此项,请添加一个Map以保存所有已计算的值。如果您拨打电话x
,则在地图中查看是否已计算{{1}}。如果是,则返回存储的值。如果没有,请计算,存储并返回。这样你也得到一个O(n)。