I think the third version is more efficient in time since it utilize more space compared to version 2 which is O(1) space. Essentially, they are the "same", we are just changing the order of two loops. Anyway, as a practice, the following is a c++ implementation. I like to use left < right in while-loop. Finally, just test whether the last number we found is valid or not.

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int left = 1, right = nums.size();
while (left < right) {
int mid = left + ((right - left) >> 1);
if (existWindow(nums, mid, s)) right = mid;
else left = mid + 1;
}
return existWindow(nums, right, s) ? right : 0;
}
bool existWindow(vector<int> &nums, int size, int s) {
int sum = 0;
for (int i = 0; i < nums.size(); ++i) {
if (i >= size) sum -= nums[i-size];
sum += nums[i];
if (sum >= s) return true;
}
return false;
}
};