Minimum change in lanes required to cross all barriers

Consider a 3 lane road of length N which includes (N + 1) points from 0 to N. A man starts at point 0 in the 2nd lane and wants to reach point N, but it is possible that there could be a barrier along the way. Given an array barrier[] of length (N + 1) where barrier[i](0 ? barrier[i] ? 3) defines a barrier on the lane at point i. If barrier[i] is 0, then there is no barrier at that point. Otherwise, there is a barrier at the barrier[i]th lane at the ith position. It is given that there will be at most one barrier in the 3 lanes at each point. The man can travel from ith point to (i + 1)th point only if there is no barrier at point (i + 1)th point. To avoid a barrier, that man just has to change to the lane where there is no barrier.
The task is to find the minimum number of changes in the lane made by the man to reach point N in any lane starting from point 0 and lane 2.
Examples:
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
Approach: The given problem can be solved using Dynamic Programming as it follows both the properties of Optimal Substructure and Overlapping Subproblems. First of all, create an array arr[] of size 3 where
- dp[0] = Minimum crosses require to reach Lane-1
- dp[1] = Minimum crosses require to reach Lane-2
- dp[2] = Minimum crosses require to reach Lane-3
If it meets a stone set dp[i] to a very large value, i.e., greater than 105 and return the minimum value from dp[0], dp[1] and dp[2]. Follow the steps below to solve the problem:
- Initialize an array dp[] with values {1, 0, 1}.
- Iterate over the range [0, N] using the variable j and performing the following tasks:
- Initialize a variable, say val as barrier[j].
- If val is greater than 0, then set the value of dp[val – 1] as 106.
- Iterate over the range [0, N] using the variable i and if the value of val is not equal to (i + 1), then set the value of dp[i] as the minimum of dp[i] or (dp[i + 1]%3 + 1) or (dp[i + 2]%3 + 1).
- After completing the above steps, print the minimum of dp[0] or dp[1] or dp[2] as the resultant number of changes of lanes.
Below is the implementation of the above approach:
C++
// C++ program for the above approachÂ
#include <bits/stdc++.h>using namespace std;Â
// Function to find the minimum number// of changes of lane requiredint 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 Codeint 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 approachclass GFG{Â
// Function to find the minimum number// of changes of lane requiredstatic 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 Codepublic 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 requireddef 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 Codebarrier = [0, 1, 2, 3, 0]N = len(barrier)Â
print(minChangeInLane(barrier, N))Â
# This code is contributed by subhammahato348. |
C#
// C# program for the above approachusing 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
<script>// Javascript program for the above approachÂ
// Function to find the minimum number// of changes of lane requiredfunction minChangeInLane(barrier, n){  let dp = [1, 0, 1];  for (let j = 0; j < n; j++)  {       // If there is a barrier, then    // add very large value    let val = barrier[j];    if (val > 0) {      dp[val - 1] = 1e6;    }Â
    for (let 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 Codelet barrier = [0, 1, 2, 3, 0];let N = barrier.length;Â
document.write(minChangeInLane(barrier, N));Â
// This code is contributed by _saurabh_jaiswal.</script> |
2
Â
Time Complexity: O(N)
Auxiliary Space: O(1)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!




