递归问题-Java-高尔夫击球的最小次数
我试图根据给定的球杆长度计算我需要的最少击球次数。您也可以将其视为给定兑换所需的最小硬币数量 我的代码是递归问题-Java-高尔夫击球的最小次数,java,arrays,recursion,Java,Arrays,Recursion,我试图根据给定的球杆长度计算我需要的最少击球次数。您也可以将其视为给定兑换所需的最小硬币数量 我的代码是 public static int golf(int holeLength, int[] clubLengths) { return golf(holeLength, clubLengths, 0); } public static int golf(int holeLength, int[] clubLengths, int shots) {
public static int golf(int holeLength, int[] clubLengths)
{
return golf(holeLength, clubLengths, 0);
}
public static int golf(int holeLength, int[] clubLengths, int shots)
{
if(holeLength==0)
shots+=0;
else if(holeLength<0)
shots=-1;
else
{
for(int i = 0; i<clubLengths.length; i++)
{
return golf(holeLength-clubLengths[i], clubLengths, shots+1);
}
}
return shots;
}
public static int golf(int holelelength,int[]clublength)
{
回程高尔夫(杆长、杆长、0);
}
公共静态内景高尔夫(内景洞长、内景[]杆长、内景杆数)
{
if(holelelength==0)
快照+=0;
else if(holelelength下面是代码中发生的情况:当函数运行第一个循环时,它将在clubLengths
中获取第一个元素,并立即返回,而不进入下一个循环。您需要遍历每个可能使用的俱乐部
以下是我的递归解决方案:
检查每个俱乐部
您可以选择使用当前俱乐部并再次使用
或者您可以选择使用当前俱乐部和下一个俱乐部
或者您可以选择不使用当前俱乐部而使用下一个俱乐部
我可以通过以下方式实现这一点:
public static int golf(int holeLength, int[] clubLengths) {
int[][] dp = int[clubLengths.length()][holeLength+1];
return golf(holeLength, clubLengths, 0, dp);
}
private static int golf(int holeLength, int[] clubLengths, int ind, int[][] dp) {
if (holeLength == 0) return 0;
if (holeLength < 0) return -1;
if (ind >= clubLengths.length()) return -1;
if (dp[ind][holeLength] != 0) return dp[ind][holeLength];
int rec1 = golf(holeLength-clubLengths[ind], clubLengths, ind, dp);
if (rec1 == -1) rec1 = Integer.MAX_VALUE;
else rec1++;
int rec2 = golf(holeLength-clubLengths[ind], clubLengths, ind+1, dp);
if (rec2 == -1) rec2 == Integer.MAX_VALUE;
else rec2++;
int rec3 = golf(holeLength, clubLengths, ind+1, dp);
if (rec3 == -1) rec3 = Integer.MAX_VALUE;
int result = Math.min(rec1, rec2);
result = Math.min(result, rec3);
if (result == Integer.MAX_VALUE) result = -1;
dp[ind][holeLength] = result;
return result;
}
public static int golf(int holelelength,int[]clublength){
int[]dp=int[clublenghts.length()][holelelength+1];
回程高尔夫(球洞长度、球杆长度、0、dp);
}
私人静态int高尔夫(int HoleleLength、int[]Clublength、int ind、int[][]dp){
如果(holelelength==0)返回0;
if(holelelength<0)返回-1;
if(ind>=clublenghts.length())返回-1;
如果(dp[ind][holelelength]!=0)返回dp[ind][holelelength];
int rec1=高尔夫(球杆长度[ind],球杆长度,ind,dp);
如果(rec1==-1)rec1=Integer.MAX_值;
else rec1++;
int rec2=高尔夫(球杆长度[ind],球杆长度,ind+1,dp);
如果(rec2==-1)rec2==Integer.MAX_值;
else rec2++;
int rec3=高尔夫(球洞长度、球杆长度、ind+1、dp);
如果(rec3==-1)rec3=Integer.MAX_值;
int result=Math.min(rec1,rec2);
结果=数学最小值(结果,rec3);
如果(result==Integer.MAX_值)result=-1;
dp[ind][holelelength]=结果;
返回结果;
}
除了递归,我还添加了dp来优化时间复杂度。因此,我的解决方案的时间复杂度将O(k*n)其中k是holelelength
,n是clubslength
中的元素数。如果您不想要dp,而只想要纯递归,您可以从上面删除dp
的所有用法,代码仍然可以工作,但速度会变慢。下面是代码中发生的情况:当函数运行第一个循环时,它会运行得更快s是clubLengths
中的第一个元素,并立即返回,无需进入下一个循环。您需要浏览每个可能使用的俱乐部
以下是我的递归解决方案:
检查每个俱乐部
您可以选择使用当前俱乐部并再次使用
或者您可以选择使用当前俱乐部和下一个俱乐部
或者您可以选择不使用当前俱乐部而使用下一个俱乐部
我可以通过以下方式实现这一点:
public static int golf(int holeLength, int[] clubLengths) {
int[][] dp = int[clubLengths.length()][holeLength+1];
return golf(holeLength, clubLengths, 0, dp);
}
private static int golf(int holeLength, int[] clubLengths, int ind, int[][] dp) {
if (holeLength == 0) return 0;
if (holeLength < 0) return -1;
if (ind >= clubLengths.length()) return -1;
if (dp[ind][holeLength] != 0) return dp[ind][holeLength];
int rec1 = golf(holeLength-clubLengths[ind], clubLengths, ind, dp);
if (rec1 == -1) rec1 = Integer.MAX_VALUE;
else rec1++;
int rec2 = golf(holeLength-clubLengths[ind], clubLengths, ind+1, dp);
if (rec2 == -1) rec2 == Integer.MAX_VALUE;
else rec2++;
int rec3 = golf(holeLength, clubLengths, ind+1, dp);
if (rec3 == -1) rec3 = Integer.MAX_VALUE;
int result = Math.min(rec1, rec2);
result = Math.min(result, rec3);
if (result == Integer.MAX_VALUE) result = -1;
dp[ind][holeLength] = result;
return result;
}
public static int golf(int holelelength,int[]clublength){
int[]dp=int[clublenghts.length()][holelelength+1];
回程高尔夫(球洞长度、球杆长度、0、dp);
}
私人静态int高尔夫(int HoleleLength、int[]Clublength、int ind、int[][]dp){
如果(holelelength==0)返回0;
if(holelelength<0)返回-1;
if(ind>=clublenghts.length())返回-1;
如果(dp[ind][holelelength]!=0)返回dp[ind][holelelength];
int rec1=高尔夫(球杆长度[ind],球杆长度,ind,dp);
如果(rec1==-1)rec1=Integer.MAX_值;
else rec1++;
int rec2=高尔夫(球杆长度[ind],球杆长度,ind+1,dp);
如果(rec2==-1)rec2==Integer.MAX_值;
else rec2++;
int rec3=高尔夫(球洞长度、球杆长度、ind+1、dp);
如果(rec3==-1)rec3=Integer.MAX_值;
int result=Math.min(rec1,rec2);
结果=数学最小值(结果,rec3);
如果(result==Integer.MAX_值)result=-1;
dp[ind][holelelength]=结果;
返回结果;
}
除了递归,我还添加了dp来优化时间复杂度。因此,我的解决方案的时间复杂度将O(k*n)其中k是holelelength
,n是clubslength
中的元素数。如果您不想要dp,只想要纯递归,您可以从上面删除dp
的所有用法,代码仍然可以工作,但速度较慢。它只检查第一个数字,因为for循环中的唯一指令是返回,因此在第一次迭代时,它将返回并取消所有剩余的迭代。您需要重新考虑您的逻辑(我不太确定您希望使用此阵列实现什么)再次阅读后,我的坏消息变得更清楚了。你可以在for循环中尝试,或者从数组中的最大值开始,如果它是有序的,检查它是否小于holelenght,或者可能不使用return并将结果放入temp变量中,在循环中的每次迭代中尝试它,只返回我试图不返回的最小shot使用return,而不是if来比较每个快照的数量,只存储最小的快照,但它不会改变任何东西(int i=0;iit只检查第一个数字,因为for循环中唯一的指令是返回,所以在第一次迭代时,它将返回并取消所有剩余的迭代。您需要重新考虑您的逻辑(我不确定使用此数组要实现什么)再次阅读后,我的坏消息变得更清楚了。你可以在for循环中尝试,或者从数组中的最大值开始,如果它是有序的,检查它是否小于holelenght,或者可能不使用return并将结果放入temp变量中,在循环中的每次迭代中尝试它,只返回我试图不返回的最小shot使用return而不是if来比较每个快照的数量,并且只存储最小的快照,但它确实存储了