Counting Good stones in a river with positive and negative steps
Geek is in a geekland which has a river and some stones in it. Initially, a geek can step on any stone. Each stone has a number on it representing the value of the exact step the geek can move. If the number is +ve then geeks can move right and if the number is -ve then geeks can move left. Bad Stones are defined as stones that if geeks steps, will reach a never-ending loop whereas good stones are stones that are safe from never-ending loops. Return the number of good stones in the river.
Input: [2, 3, -1, 2, -2, 4, 1]
Explanation: Index 3, 5 and 6 are safe only. As index 1, 4, 2 forms a cycle and from index 0 you can go to index 2 which is part of cycle.
Input: [1, 0, -3, 0, -5, 0]
Explanation: Index 2 and 4 are safe only. As index 0, 1, 3, 5 form cycle.
Intuition: The intuition/idea is as follows:
The intuition of this approach is that we start from any stone present in the given array and we will make recursive call for other stones, initially we assume that the stones which appears in the recursive call are bad stone but if we can reach at the last index of the array then we return the recursive call to the stone from where we start our journey for each and every recursive call and we will mark them as good stones other wise they remains bad stone.
Approach: To solve the problem follow the below idea:
The problem can be solved using Dynamic Programming. The idea here is to maintain a visited array or list of size equal to the size of the given array which is initialized by -1. If the value of visited array at any index, i is -1 that means we have not visited the stone present at the index, i in the given array. Whenever we start our journey from any index of the given array we mark the value of visited array at the same index as 0 value and we do it recursively for each and every index of the given array. If we reach out of the array by following some path than the indexes that appears in this path we mark them as good indexes and value the visited array at those indexes will be 1 which means “We visit those indexes to reach out of the array and the stones which are present on those indexes are said to be good stones”, otherwise value of the visited array at those indexes remains 0.
Below are the steps for the above approach:
- Declare a visited array, vis of size equal to the size of input array/vector globally so that it can be accessed in any function.
- Initialize the visited array, vis by -1 which denotes that the stones are not visited.
- Iterate the input vector as we can start the journey from any index, for each index we will check if is it a good stone or bad stone using a helper function solve().
- Check if vis[i] == -1, and call the solve() function that takes two arguments, input array, and current index of the stone, i.
- In the helper function,
- check if, i < 0 or i ≥ input array size, that means index i has already reached out of the array so, return 1.
- check if vis[i] != -1, which means index i has already been visited, and return vis[i].
- If the above two are not the case, that means the stone at index i is not visited previously and we are still inside the input array. So, mark vis[i] = 0 to show this is a bad stone.
- Recursively call solve() function. solve() function returns some integer value either 0 or 1 which will be stored in the visited array, vis[i] = solve(array, i+array[i]).
- When the recursive call is completed return the value of the visited array, vis at index i, return vis[i].
- Initialize one variable, say, count by 0 to calculate the number of good stones.
- Iterate the visited array and check if the value of the visited array at any index is 1, vis[i] = 1 which means a stone at the same index is a good stone, increment count variable by 1.
- Return the value of the count variable.
Below is the implementation for the above approach:
Time Complexity: O(N), N is the number of stones
Auxiliary Space: O(N)
Please Login to comment...