<p>You are given a <strong>0-indexed</strong> array of integers <code>nums</code> of length <code>n</code>. You are initially positioned at <code>nums[0]</code>.</p>

<p>Each element <code>nums[i]</code> represents the maximum length of a forward jump from index <code>i</code>. In other words, if you are at <code>nums[i]</code>, you can jump to any <code>nums[i + j]</code> where:</p>

<ul>
	<li><code>0 &lt;= j &lt;= nums[i]</code> and</li>
	<li><code>i + j &lt; n</code></li>
</ul>

<p>Return <em>the minimum number of jumps to reach </em><code>nums[n - 1]</code>. The test cases are generated such that you can reach <code>nums[n - 1]</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> nums = [2,3,1,1,4]
<strong>Output:</strong> 2
<strong>Explanation:</strong> The minimum number of jumps to reach the last index is 2. Jump 1 step from index 0 to 1, then 3 steps to the last index.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> nums = [2,3,0,1,4]
<strong>Output:</strong> 2
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= nums.length &lt;= 10<sup>4</sup></code></li>
	<li><code>0 &lt;= nums[i] &lt;= 1000</code></li>
	<li>It&#39;s guaranteed that you can reach <code>nums[n - 1]</code>.</li>
</ul>

#include <vector>
#include <queue>
#include <tuple>

class Solution {
public:
    int jump(std::vector<int>& nums) {
        return BFS(nums);
    }


private:

    int BFS(std::vector<int>& nums)
    {
        if (nums.size() == 1) return 0;  // Already at the end

        int n = nums.size() - 1;
        int shortest_jump = 0;

        // queue stores the current index and number of jumps to reach there
        std::queue<int> q;
        q.push(0);

        // visited array to mark indices that have been processed
        std::vector<bool> visited(nums.size(), false);
        visited[0] = true;

        while (!q.empty())
        {
            int size = q.size();
            shortest_jump++;  // Increase jump count at each level

            for (int i = 0; i < size; ++i)
            {
                int idx = q.front();
                q.pop();

                // Explore all reachable indices from the current index
                for (int j = 1; j <= nums[idx]; ++j)
                {
                    int new_idx = idx + j;

                    if (new_idx >= n) 
                    {
                        return shortest_jump;  // Found the shortest path to the end
                    }

                    if (!visited[new_idx])
                    {
                        q.push(new_idx);
                        visited[new_idx] = true;
                    }
                }
            }
        }

        return -1; // If there's no way to reach the end
    }


};
20100