Here's the solution:
function isPerfectSquare(num)
if num = 1 then
return true
left := 1
right := num
while left ≤ right
mid := left + (right - left) / 2
square := mid × mid
if square = num then
return true
else if square < num then
left := mid + 1
else
right := mid - 1
return false
This runs in time. Binary search halves the search space each iteration, giving logarithmic complexity.