add optimized version, space O(1)