The second block is more likely to lead to problems for the simple reason that global variables often lead to unexpected side-effects.
Quite the contrary in this case. In fact, the second example (the one with the global) is the only
one that is going to work properly.
The reason being is that there is a difference in how locally declared variables are handled vs how
global variables are handled.
ALL global variables are zeroed out by the C startup code prior to your code being called. Local variables are not.
When a local variable is declared, space is allocated for it, but it is not zeroed. So while the initial contents
of a global is always zero, the initial contents of a local that is not explicitly initialized
is undefined and cannot be assumed to be anything.
So in the example using the global contactedOK, its initial value in loop() will be 0 (because the
startup code zeroed it), in the example where it is a local, its initial value is undefined and could be anything.
This looks like it will be an issue if contactedOK is not initially 0.
Also in the global example:
The assignment of 0 to i is unneeded and in fact the declaration may cause the compiler to waste 2 bytes of flash to
store that 0. (I haven't looked to see if the compiler is smart enough to ignore this assignment)
By explicitly assigning an initial value for a variable(0 in this case), the compiler and startup code
must ensure that the desired initial value is set,
so rather than letting the startup up code clear the variable to 0, the startup code must
fill in the value of the variable with the desired initial value (which also happens to be 0 in this case).
The reason I say may, is I've not looked to see if gcc is smart enough to ignore an explicit assignment of 0
to a global and let the start up code clear it instead. It might be smart enough to do this.