穿过所有障碍物所需的最小车道变化
考虑一条长度为N的 3 车道道路,其中包括从0到N的(N + 1)个点。一个人从第二条车道的0点开始,想要到达N点,但沿途可能会有障碍物。给定一个长度为(N + 1)的数组屏障 [] ,其中屏障 [i](0 ≤ 屏障 [i] ≤ 3)定义车道上的屏障 在点i 。如果barrier[i]为0 ,那么此时没有障碍。否则,在第i个位置的第 barrier[ i ] 车道上有一个障碍。假设在每个点的 3 条车道中最多有一个障碍物。只有在第 (i + 1 )点没有障碍物时,该人才能从第 i点行进到第( i + 1)点。为了避开障碍物,那个人只需改变到没有障碍物的车道即可。
任务是在从点0和车道 2开始的任何车道上找到该人在到达点N的车道上所做的最小更改次数。
例子:
Input: barrier[] = [0, 1, 0, 2, 3, 1, 2, 0]
Output: 3
Explanation:
In the below image the green circle are the barriers and the optimal path is shown in the diagram and the change in lane is shown by green arrow:
Input: barrier[] = [0, 2, 0, 1, 3, 0]
Output: 2
方法:给定的问题可以使用动态规划来解决,因为它遵循最优子结构和重叠子问题的属性。首先,创建一个大小为 3 的数组arr[] ,其中
- dp[0] = 到达 Lane-1 所需的最少交叉次数
- dp[1] = 到达 Lane-2 所需的最少交叉次数
- dp[2] = 到达 Lane-3 所需的最少交叉次数
如果遇到石头,则将dp[i]设置为非常大的值,即大于 10 5并从dp[0] 、 dp[1]和dp[2]返回最小值。请按照以下步骤解决问题:
- 使用值{1, 0, 1}初始化数组dp[] 。
- 使用变量j迭代范围[0, N]并执行以下任务:
- 初始化一个变量,比如val作为barrier[j] 。
- 如果val大于0 ,则将dp[val – 1]的值设置为10 6 。
- 使用变量i在[0, N]范围内迭代,如果val的值不等于(i + 1) ,则将dp[i]的值设置为dp[i]或(dp[ i + 1]%3 + 1)或(dp[i + 2]%3 + 1) 。
- 完成上述步骤后,打印出dp[0]或dp[1]或dp[2]的最小值作为变道次数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number
// of changes of lane required
int minChangeInLane(int barrier[], int n)
{
int dp[] = { 1, 0, 1 };
for (int j = 0; j < n; j++) {
// If there is a barrier, then
// add very large value
int val = barrier[j];
if (val > 0) {
dp[val - 1] = 1e6;
}
for (int i = 0; i < 3; i++) {
// Add the minimum value to
// move forward with or
// without crossing barrier
if (val != i + 1) {
dp[i] = min(dp[i],
min(dp[(i + 1) % 3],
dp[(i + 2) % 3])
+ 1);
}
}
}
// Return the minimum value of
// dp[0], dp[1] and dp[2]
return min(dp[0], min(dp[1], dp[2]));
}
// Driver Code
int main()
{
int barrier[] = { 0, 1, 2, 3, 0 };
int N = sizeof(barrier) / sizeof(barrier[0]);
cout << minChangeInLane(barrier, N);
return 0;
}
Java
// Java program for the above approach
class GFG
{
// Function to find the minimum number
// of changes of lane required
static int minChangeInLane(int barrier[], int n)
{
int dp[] = { 1, 0, 1 };
for (int j = 0; j < n; j++) {
// If there is a barrier, then
// add very large value
int val = barrier[j];
if (val > 0) {
dp[val - 1] = (int) 1e6;
}
for (int i = 0; i < 3; i++) {
// Add the minimum value to
// move forward with or
// without crossing barrier
if (val != i + 1) {
dp[i] = Math.min(dp[i],
Math.min(dp[(i + 1) % 3],
dp[(i + 2) % 3])
+ 1);
}
}
}
// Return the minimum value of
// dp[0], dp[1] and dp[2]
return Math.min(dp[0], Math.min(dp[1], dp[2]));
}
// Driver Code
public static void main(String[] args)
{
int barrier[] = { 0, 1, 2, 3, 0 };
int N = barrier.length;
System.out.print(minChangeInLane(barrier, N));
}
}
// This code is contributed by shikhasingrajput
Python3
# Python program for the above approach
# Function to find the minimum number
# of changes of lane required
def minChangeInLane(barrier, n):
dp = [1, 0, 1]
for j in range(n):
# If there is a barrier, then
# add very large value
val = barrier[j]
if (val > 0):
dp[val - 1] = 1000000
for i in range(3):
# Add the minimum value to
# move forward with or
# without crossing barrier
if (val != i + 1):
dp[i] = min(dp[i],
min(dp[(i + 1) % 3],
dp[(i + 2) % 3])
+ 1)
# Return the minimum value of
# dp[0], dp[1] and dp[2]
return min(dp[0], min(dp[1], dp[2]))
# Driver Code
barrier = [0, 1, 2, 3, 0]
N = len(barrier)
print(minChangeInLane(barrier, N))
# This code is contributed by subhammahato348.
C#
// C# program for the above approach
using System;
public class GFG
{
// Function to find the minimum number
// of changes of lane required
static int minChangeInLane(int[] barrier, int n)
{
int []dp = { 1, 0, 1 };
for (int j = 0; j < n; j++) {
// If there is a barrier, then
// add very large value
int val = barrier[j];
if (val > 0) {
dp[val - 1] = (int) 1e6;
}
for (int i = 0; i < 3; i++) {
// Add the minimum value to
// move forward with or
// without crossing barrier
if (val != i + 1) {
dp[i] = Math.Min(dp[i],
Math.Min(dp[(i + 1) % 3],
dp[(i + 2) % 3])
+ 1);
}
}
}
// Return the minimum value of
// dp[0], dp[1] and dp[2]
return Math.Min(dp[0], Math.Min(dp[1], dp[2]));
}
// Driver Code
static public void Main (){
// Code
int []barrier = { 0, 1, 2, 3, 0 };
int N = barrier.Length;
Console.Write(minChangeInLane(barrier, N));
}
}
// This code is contributed by Potta Lokesh
Javascript
2
时间复杂度: O(N)
辅助空间: O(1)