我最近接受了实习生职位的采访,其中一个问题与此相似:
输入:n表示操作次数,k表示您无法步进的楼梯 上
问题:杰克在他想要达到的地方有很多行动 最大步数但不能踩到第k个楼梯。对于每一个 行动,杰克可以留在他现在的步骤或跳跃我的步骤,如果他 是他的第i个动作,这一直持续到他完成了他的第n个 动作。
输出:n次操作中可以达到的最大楼梯
它是通过Hackerrank(与那里的采访者)进行测试的,我只通过了8个测试用例中的3个,剩下的时间用完了
这是我的解决方案,它是动态编码的,我无法对其进行优化,并且想知道是否有更优化的解决方案:
static int maxStep(int n, int k) {
int result = 0;
if (n == 0) {
return result;
}
return maxStepHelper(n,0, k, result);
}
static int maxStepHelper(int n,int i,int k,int result) {
// At n+1 steps, previous steps' results are recorded and this is mainly used to stop and show previous results
if (i == n+1) {
return result;
}
int nextStep = i + result;
if (nextStep == k) {
return maxStepHelper(n,i+1,k,result);
}
return Math.max(maxStepHelper(n,i+1,k,result),maxStepHelper(n,i+1,k,result+i));
}
请注意,我使用了一种可能没有帮助的递归方法
答案 0 :(得分:4)
这里不需要递归或动态编程;这只是一些数学。
如果您在每个回合中执行i
步骤,则会执行(n * (n+1)) / 2
步骤。如果k
是等式的整数解,您将落在k
步骤上:
k = (n * (n+1)) / 2
重新排列:
0 = n^2 + n - 2*k
这是n
中的二次方程:
n = (-1 +/- sqrt(1 + 4*1*2*k)) / 2
如果sqrt(1 + 8*k)
是奇数,则只有整数解。
所以:
如果sqrt(1 + 8*k)
是一个奇数,你将落在k
步。所以,只是不要对第一个操作采取任何步骤,并且您将错过k
1个。最大步数为(n * (n+1)) / 2 - 1
。
这是你想要错过的第一个动作,因为1是你可以缩短的最小步数。如果你错过了第二个动作,你将比最大动作短2步。
否则,只需对每个操作执行i
步骤,最大步数为(n * (n+1)) / 2