A side effect of parsing the querystring, filtering it, then re-encoding it is that the implied indexes (empty square braces) will be replaced with explicit indexes. Without calling array_unique() on the filtered temporary array, there will be a potential gap in the in keys - this may or may not be problematic. Also, the square braces themselves will be URL encoded (which makes the string harder for humans to read -- if it matters). https://3v4l.org/eWM9O
Alternatively, you can use a regular expression to manipulate the predictable and repetitive string without parsing it. The pattern uses a conditional expression to correctly match the leading or trailing & (but never both) and it uses a word boundary to ensure that only the whole integer is matched when filtering.
Code: (Demo with a few examples)
echo preg_replace('#(&)?navMenu\[]=' . preg_quote($find) . '\b(?(1)|&?)#', '', $str);
Largely similar content: Replace a whole integer match in a delimited string and a maximum of one of its adjacent commas
6entry to readnavMenu[]=1&navMenu[]=2&navMenu[]=3&navMenu[]=4&navMenu[]=5?)$_GET['navMenu']?