在给定两个数组表示路径的情况下,这是一个关于Java的小练习。

huangapple go评论93阅读模式
英文:

Small exercise for Java given two arrays which represents a path

问题

给定两个数组,表示一条路径,数组中的每个元素代表驾驶员行驶所需的时间,编写一个方法选择他可以选择的最快路径。驾驶员只能在两个数组之间切换一次。

例如,给定以下数组:

int[] road1 = new int[] { 5, 4, 5, 8, 12, 9, 9, 3 };
int[] road2 = new int[] { 7, 3, 3, 12, 10, 2, 10, 7 };

输出应为 49,因为驾驶员将从 road2 开始,并在索引 6 处切换到第二个数组。

编辑:
我的问题是,在切换到另一个数组后,如何使递归停止?我尝试过放置计数标记,但没有奏效,并且恢复到了原始输出。我对递归的工作原理是否有所遗漏?

我的代码打印出 53,但应该打印 49。

我的代码:

public class MyClass {

    public static int shortestRoad(int[] road1, int[] road2) {
        return shortestRoadNumbers(road1, road2, 0);
    }

    private static int shortestRoadNumbers(int[] road1, int[] road2, int index) {
        if (index == road1.length || index == road2.length) {
            return 0;
        }
        if (road1[index] >= road2[index] && road1[index + 2] >= road2[index + 2]) {
            return (road2[index] + shortestRoadNumbers(road1, road2, index + 1));
        } else {
            return (road1[index] + shortestRoadNumbers(road1, road2, index + 1));
        }
    }

    public static void main(String args[]) {
        int[] road1 = new int[] { 5, 4, 5, 8, 12, 9, 9, 3 };
        int[] road2 = new int[] { 7, 3, 3, 12, 10, 2, 10, 7 };
        MyClass.shortestRoad(road1, road2);
        int result = MyClass.shortestRoad(road1, road2);
        System.out.println(result);
    }
}
英文:

Given two arrays which represents a path and each element in the array represent the time it takes the driver to travel, write a method that chooses the fastest path he can take. The driver can switch paths only once between arrays.
For example the following arrays:

int[] road1 = new int[] { 5, 4, 5, 8, 12, 9, 9, 3 };
int[] road2 = new int[] { 7, 3, 3, 12, 10, 2, 10, 7 };

the output should be 49 since the driver will start at road2 and switch at index 6 to the second Array.

Edit:
My question is how do I make the recursion stop after switching to the other array? I tried to put a counter marker but it didn't work and I reverted back to my original output. Am I missing something about how recursion works?

My code prints 53 where it should print 49.

My code:

public class MyClass {

    public static int shortestRoad(int[] road1, int[] road2) {
        return shortestRoadNumbers(road1, road2, 0);
    }

    private static int shortestRoadNumbers(int[] road1, int[] road2, int index) {
        if (index == road1.length || index == road2.length) {
            return 0;
        }
        if (road1[index] >= road2[index] && road1[index + 2] >= road2[index + 2]) {
            return (road2[index] + shortestRoadNumbers(road1, road2, index + 1));
        } else {
            return (road1[index] + shortestRoadNumbers(road1, road2, index + 1));
        }

    }

    public static void main(String args[]) {
        int[] road1 = new int[] { 5, 4, 5, 8, 12, 9, 9, 3 };
        int[] road2 = new int[] { 7, 3, 3, 12, 10, 2, 10, 7 };
        MyClass.shortestRoad(road1, road2);
        int result = MyClass.shortestRoad(road1, road2);
        System.out.println(result);
    }
}

</details>


# 答案1
**得分**: 0

```java
让下面的模式来说明您的问题  
 [![enter image description here][1]][1]

我们有两条路径,每条路径包含许多节点(值),我们可以在两条路径之间切换一次。找到使得分数最小化的节点(值)的最佳组合。  
我们可以区分4种情况:  
1- 在不切换的情况下,第一条路径的值的总和。  
2- 在不切换的情况下,第二条路径的值的总和。  
3- 从第一条路径的节点直到节点 i 的值的总和,然后切换到第二条路径从节点 i+1 开始的值的总和(从节点 i+1 到末尾)。  
4- 第3点的相反情况。  

    static int shortestRoad(int road1[], int road2[])
    {
    	// 情况1
    	int bestValue = sumValues(road1,0);
    
    	// 情况2
    	int sumValuesRoad2 = sumValues(road2,0);
    	if ( sumValuesRoad2 &lt; bestValue)
    		bestValue = sumValuesRoad2;
    
    	// 情况3:从路线1到路线2的所有组合的最佳值
    	int bestValuesSwitchFromRoad1ToRoad2 = shortestRoad_Switch_RoadFrom_RoadTo(road1, road2);
    	if ( bestValuesSwitchFromRoad1ToRoad2 &lt; bestValue)
    		bestValue = bestValuesSwitchFromRoad1ToRoad2;
    
    	// 情况4:从路线2到路线1的所有组合的最佳值
    	int bestValuesSwitchFromRoad2ToRoad1 =  shortestRoad_Switch_RoadFrom_RoadTo(road2, road1);
    
    	if ( bestValuesSwitchFromRoad2ToRoad1 &lt; bestValue)
    		bestValue = bestValuesSwitchFromRoad2ToRoad1;
    
    	return bestValue;
    }

对给定数组从 idx 到末尾进行求和: 

    static int sumValues(int array[], int idx_from)
    {
    	int sum = 0;
    	for (int i = idx_from; i&lt;array.length; ++i)
    		sum += array[i];
    
    	return sum;
    }

情况3和4:

    static int shortestRoad_Switch_RoadFrom_RoadTo(int[] road_from, int[] road_to)
    {
    	int sumValues_RoadFrom_til_idx = 0;
    	int sumValues_RoadFrom_idx_switch_RoadTo = 0;
    	int bestValue = Integer.MAX_VALUE;
    
    	for (int i = 0; i&lt;road_from.length-1; ++i)
    	{
    		sumValues_RoadFrom_til_idx += road_from[i];
    
    		sumValues_RoadFrom_idx_switch_RoadTo = sumValues_RoadFrom_til_idx+sumValues(road_to,i+1);
    
    		if(sumValues_RoadFrom_idx_switch_RoadTo &lt; bestValue )
    			bestValue = sumValues_RoadFrom_idx_switch_RoadTo;
    	}
    
    	return bestValue;
    }

驱动代码:

    public static void main(String[] args) 
    {
    	
    	int road1[] = { 5, 4, 5, 8, 12, 9, 9, 3 };
    	int road2[] = { 7, 3, 3, 12, 10, 2, 10, 7 };
    
    	int road_a[] = { 1, 1, 1, 1, 1, 9, 9, 9,9,9 };
    	int road_b[] = { 9, 9, 9, 9, 9, 1, 1, 1,1,1 };
    
    	int road_c[] = { 1, 1, 1, 1, 1, 2 };
    	int road_d[] = { 9, 9, 9, 9, 9, 1, 1, 1,1,1 };
    
    	System.out.println(&quot;best road1, road2 = &quot;+shortestRoad(road1,road2));
    	System.out.println(&quot;best road_a, road_b = &quot;+shortestRoad(road_a,road_b));
    	System.out.println(&quot;best road_c, road_d = &quot;+shortestRoad(road_c,road_d));
    
    	return 0;
    }

结果:

    best road1, road2 = 49
    best road_a, road_b = 10
    best road_c, road_d = 7 

注:
在您的示例中,最佳路径是从 road2 开始,然后在 i=5 处切换到 road 1(i 从 0 开始)

    {    5, 4, 5, 8, 12, 9,  --&gt;9, 3 }  
    { --&gt;7, 3, 3, 12, 10, 2 /, 10, 7 }

[1]: https://i.stack.imgur.com/qA74k.png
英文:

Let the following schema to illustrate your problem
在给定两个数组表示路径的情况下,这是一个关于Java的小练习。

We have two paths, and each path contain many nodes (values) , we can switch from one path to another just one time. Find the best combination of nodes (values) that minimise the score.
We can distinguish 4 cases:
1- the sum of the values of the first path without switching.
2-the sum of the values of the second path without switching.
3-the sum of the values from the first path until a node i, then switch to path second path from node i+1 (sum from node+1 til the end)
4-the inverse of the point 3.

static int shortestRoad(int road1[], int road2[])
{
	// case 1
	int bestValue = sumValues(road1,0);

	// case 2
	int sumValuesRoad2 = sumValues(road2,0);
	if ( sumValuesRoad2 &lt; bestValue)
		bestValue = sumValuesRoad2;

	// case 3: best values of all combination from road 1 to road 2
	int bestValuesSwitchFromRoad1ToRoad2 = shortestRoad_Switch_RoadFrom_RoadTo(road1, road2);
	if ( bestValuesSwitchFromRoad1ToRoad2 &lt; bestValue)
		bestValue = bestValuesSwitchFromRoad1ToRoad2;

	// case 4: best values of all combination from road 2 to road 1
	int bestValuesSwitchFromRoad2ToRoad1 =  shortestRoad_Switch_RoadFrom_RoadTo(road2, road1);

	if ( bestValuesSwitchFromRoad2ToRoad1 &lt; bestValue)
		bestValue = bestValuesSwitchFromRoad2ToRoad1;

	return bestValue;
}

sum the values of a given array from idx til the end:

static int sumValues(int array[], int idx_from)
{
	int sum = 0;
	for (int i = idx_from; i&lt;array.length; ++i)
		sum += array[i];

	return sum;
}

case 3 and 4:

static int shortestRoad_Switch_RoadFrom_RoadTo(int[] road_from, int[] road_to)
{
	int sumValues_RoadFrom_til_idx = 0;
	int sumValues_RoadFrom_idx_switch_RoadTo = 0;
	int bestValue = Integer.MAX_VALUE;

	for (int i = 0; i&lt;road_from.length-1; ++i)
	{
		sumValues_RoadFrom_til_idx += road_from[i];

		sumValues_RoadFrom_idx_switch_RoadTo = sumValues_RoadFrom_til_idx+sumValues(road_to,i+1);

		if(sumValues_RoadFrom_idx_switch_RoadTo &lt; bestValue )
			bestValue = sumValues_RoadFrom_idx_switch_RoadTo;
	}

	return bestValue;
}

Driver code:

public static void main(String[] args) 
{
	
	int road1[] = { 5, 4, 5, 8, 12, 9, 9, 3 };
	int road2[] = { 7, 3, 3, 12, 10, 2, 10, 7 };

	int road_a[] = { 1, 1, 1, 1, 1, 9, 9, 9,9,9 };
	int road_b[] = { 9, 9, 9, 9, 9, 1, 1, 1,1,1 };

	int road_c[] = { 1, 1, 1, 1, 1, 2 };
	int road_d[] = { 9, 9, 9, 9, 9, 1, 1, 1,1,1 };

	System.out.println(&quot;best road1, road2 = &quot;+shortestRoad(road1,road2));
	System.out.println(&quot;best road_a, road_b = &quot;+shortestRoad(road_a,road_b));
	System.out.println(&quot;best road_c, road_d = &quot;+shortestRoad(road_c,road_d));

	return 0;
}

Results:

best road1, road2 = 49
best road_a, road_b = 10
best road_c, road_d = 7 

ps:
the best path in your example is begin from road2 and then switch to road 1 at i=5 (i begin from 0)

{    5, 4, 5, 8, 12, 9,  --&gt;9, 3 }  
{ --&gt;7, 3, 3, 12, 10, 2 /, 10, 7 }

答案2

得分: 0

public static int shortestRoad(int[] road1, int[] road2) {
    int sumRoad1Only = 0;
    int sumRoad2Only = 0;
    for (int i = 0; i < road1.length; i++) {
        sumRoad1Only += road1[i];
        sumRoad2Only += road2[i];
    }

    int roadIndex1 = road1.length - 1;
    int roadIndex2 = road2.length - 1;
    int totalSumRoad1 = sumRoad1Only;
    int totalSumRoad2 = sumRoad2Only;

    int max = 0;
    int indexOfSwitch = 0;
    int diff = 0;

    while (roadIndex1 >= 0 && roadIndex2 >= 0) {
        diff = Math.abs(totalSumRoad2 - totalSumRoad1);
        if (diff > max) {
            max = diff;
            indexOfSwitch = roadIndex1;
        }
        totalSumRoad1 -= road1[roadIndex1];
        totalSumRoad2 -= road2[roadIndex2];
        roadIndex1--;
        roadIndex2--;
    }

    if (indexOfSwitch == road1.length - 1) {
        indexOfSwitch--;
    }

    int begin1 = 0;
    int begin2 = 0;
    for (int k = 0; k <= indexOfSwitch; k++) {
        begin1 += road1[k];
        begin2 += road2[k];
    }

    int end1 = sumRoad1Only - begin1;
    int end2 = sumRoad2Only - begin2;

    int begin1End2 = begin1 + end2;
    int begin2End1 = begin2 + end1;

    return Math.min(Math.min(sumRoad1Only, sumRoad2Only), Math.min(begin1End2, begin2End1));
}
英文:
public static int shortestRoad(int[]road1, int[]road2)
{
int sumRoad1Only = 0;
int sumRoad2Only = 0;
for(int i=0; i&lt;road1.length; i++)
{
sumRoad1Only += road1[i];
sumRoad2Only += road2[i];
}

Those sums are for the option that the driver chooses one lane, and doesn't change it until the end. Now, we can find the switch index, for options like starting at one road, and switching to the other. In this specific question I realized that the best point of switch between the arrays - is where the difference between the two collected sums until a certain index is the largest. In your example, it is index 6. That doesn't say that switching a lane is always giving a smaller sum.

int roadIndex1 = road1.length-1;
int roadIndex2 = road2.length-1;
int totalSumRoad1 = sumRoad1Only;
int totalSumRoad2 = sumRoad2Only;
int max = 0;
int indexOfSwitch = 0;
int diff = 0;
while(roadIndex1 &gt;=0 &amp;&amp; roadIndex2 &gt;=0)
{
diff = Math.abs(totalSumRoad2 - totalSumRoad1);
if(diff &gt; max)
{
max = diff;
indexOfSwitch = roadIndex1;
}
totalSumRoad1 -= road1[roadIndex1];
totalSumRoad2 -= road2[roadIndex2];
roadIndex1--;
roadIndex2--;
}

If the index of switch is at last index, we shall move it one left, so there be a transition between the arrays.

if(indexOfSwitch == road1.length-1)
{
indexOfSwitch--;
}

now we found the indexOfSwitch, we can calculate the options of starting at road1, and switching exactly once to road2, and vice versa:

int begin1 = 0;
int begin2 = 0;
for(int k = 0; k&lt;=indexOfSwitch; k++)
{
begin1 += road1[k];
begin2 += road2[k];
}
int end1 = sumRoad1Only - begin1;
int end2 = sumRoad2Only - begin2;
int begin1End2 = begin1 + end2;
int begin2End1 = begin2 + end1;

and when we find all the options, we can return the minimum.

return Math.min(Math.min(sumRoad1Only, sumRoad2Only), Math.min(begin1End2, begin2End1));

huangapple
  • 本文由 发表于 2020年7月23日 22:18:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/63056442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定