Leetcode【279、343】
문제 해결 방법:
이 문제는 정정수 n을 주고 이를 제곱수 가산인자로 분해하여 분해된 인자를 가장 적게 하는 것이다.
이 문제는 실제로Leetcode[DP, BFS]와 322.Coin Change는 비슷합니다.우리는 <=n의 제곱수 인자를 동전 종류수로 하고 n을 바꿔야 할 잔돈으로 생각하면 같은 방법인 DP와 BFS를 사용하여 해답을 구할 수 있다.
메서드 1(DP, TLE):
Letcode 322와 유사하게 동적 기획을 사용하고 시간 복잡도 O(n*sqrt(n))를 사용하지만 DP 방법은 이 문제에서 시간을 초과했습니다. 참고 코드는 다음과 같습니다.
Python3 구현:
class Solution:
def numSquares(self, n: int) -> int:
dp = [i for i in range(n + 1)] # dp dp[i]=i
for i in range(2, int(math.sqrt(n)) + 1):
sqr = i * i #
for j in range(sqr, n+1):
dp[j] = min(dp[j], dp[j-sqr] + 1) # dp[i]
return dp[-1]
메서드 2(BFS, 시간 복잡도 O(n*sqrt(n), AC):
Letcode 322와 유사하며, 사용 범위가 우선이고, 시간 복잡도 O (n*sqrt (n) 이지만, AC를 사용할 수 있습니다.
Python3 구현:
class Solution:
def numSquares(self, n: int) -> int:
sn = [] #
for i in range(1, int(math.sqrt(n)) + 1):
sn.append(i * i)
visited = [False] * (n + 1) #
visited[0] = True
q = collections.deque()
q.append((0, 0))
step = 0
while True:
while len(q) > 0 and q[0][1] == step:
x, _ = q.popleft() #
if x == n: #
return step
for num in sn: #
if x + num <= n and visited[x+num] == False:
q.append((x+num, step+1))
visited[x+num] = True
step += 1
return -1 #
메서드 3(Math, 시간 복잡도 O(sqrt(n), AC):
사실 이 문제의 가장 좋은 해법은 하나의 수학 공식인 4제곱과 정리를 사용하는 것이다.
4제곱정리: 어떤 정수든지 네 정수를 초과하지 않는 제곱의 합을 나타낼 수 있다.
그러면 이 문제의 해법은 매우 간단해진다. 우리의 결과는 1, 2, 3, 4라는 네 가지 가능성밖에 없다.
또 하나의 중요한 추론이 있다.
4수의 제곱과 정리를 만족시키는 수 n(이곳은 4개의 수로 구성되어 있고 4개보다 작으면 안 된다)을 만족시키려면 반드시 n=(4^a)*(8b+7)을 만족시켜야 한다.
따라서 우리는 이 문제의 해법을 얻을 수 있다.
이 문제의 시간 복잡도는 n이 1개 또는 2개의 제곱수로 구성된 상황을 판단할 때 주로 소모된다. 시간 복잡도는 O(sqrt(n)이다.여기서 프로그래밍을 할 때 주의해야 할 점이 하나 있다. 예를 들어 n=25와 같은 것은 2(즉 3*3+4*4)를 되돌려주는 것이 아니라 1(즉 5*5)을 되돌려줘야 한다. 따라서 우리의 제곱수는 큰 (int(sqrt(n))에서 작은 (1)까지 가져와야 3*3+4*4가 먼저 나타나지 않는다는 것을 보장할 수 있다.
Python3 구현:
class Solution:
def numSquares(self, n: int) -> int:
while n % 4 == 0: #(4^a)*(8b+7) 8b+7
n //= 4
if n % 8 == 7: # 7, 4
return 4
for i in range(int(math.sqrt(n)), 0, -1): # 1 2 ,
if i * i == n: #
return 1
j = int(math.sqrt(n - i * i)) #
if i * i + j * j == n: #
return 2
return 3 # 3
질문 설명: [Math] 343.Integer Break
문제 해결 방법:
이 문제는 정수 n을 주고 이를 약간의 정수 덧셈 인자로 분해하여 분해된 인자의 곱셈이 가장 크도록 하는 것이다.
이 문제는 데이터 범위를 보면 DFS 소급법이 안 될 것이기 때문에 규칙을 찾을 수 있다.처음에 숫자 12를 생각했을 때
3 * 3 * 3 * 3
의 분해 결과가 4 * 4 * 4
(또는 2 * 2 * 2 * 2 * 2 * 2
)의 분해 결과보다 크다는 것을 발견했기 때문에 분해 중의 인자는 가능한 한 4(또는 2)가 아닌 3을 많이 포함해야 한다고 추측했다.앞의 몇 개의 숫자의 결과를 순서대로 쓸 수 있다.
이로부터 법칙을 발견할 수 있다. dp[n]:3 * dp[n-3]
따라서 n<=6에 대해 상술한 결과를 직접 반환한다.n> 6에 대해 매번 결과를 3으로 곱한 후 n을 3으로 빼고 n<=6까지 누적된 결과를 n으로 곱하면 답이다.
이런 방법의 시간 복잡도는 O(n)이고 공간 복잡도는 O(1)이다.
Python3 구현:
class Solution:
def integerBreak(self, n: int) -> int:
ansTo6 = [0, 1, 1, 2, 4, 6, 9]
ans = 1
while n > 6:
ans *= 3 #
n -= 3
return ans * ansTo6[n] # n
향상된 기능:
사실 상술한 절차를 개선하여 시간의 복잡도를 O(1)로 얻는 방법도 얻을 수 있다.즉, 3에 대한 나머지를 판단하고 나머지에 따라 곱셈 결과를 직접 계산한다.코드는 다음과 같습니다.
class Solution:
def integerBreak(self, n: int) -> int:
if n == 2: return 1
if n == 3: return 2
if n % 3 == 0: return 3 ** (n//3)
if n % 3 == 1: return 3 ** (n//3-1) * 4
if n % 3 == 2: return 3 ** (n//3) * 2
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.