DP way
class Solution:
def winnerSquareGame(self, n: int) -> bool:
""" tc O(Nsqrt(N)) sc O(N)
"""
#dp[i] will player win with i stone
dp = [False]*(n+1)
#dp[1] = True
for i in range(1,n+1):
for k in range(1,int(sqrt(i))+1):
if dp[i-k*k] == False: # i - k*k >= 0 next player will lose ==> current player must win
dp[i] = True
break
return dp[n]
another DP way
class Solution:
def winnerSquareGame(self, n: int) -> bool:
""" tc O(Nsqrt(N)) sc O(N)
"""
#dp[i]== False Alice player win with i stone, dp[i] == False : bob must win
dp = [False]*(n+1)
for a in range(n+1):
if dp[a]:
continue
for k in range(1,int(sqrt(n))+1):
if a + k*k <= n: # assuming i can go to a by removing b*b steps
dp[a + k*k] = True
else:
break
return dp[n]