Published 2021. 9. 27. 14:44
728x90
📌 첫 번째 풀이 (시간 초과)
우선 제일 먼저 생각난 것은 for문을 돌리면서 자신을 제외한 모든 수를 곱한 것을 새로운 arr배열에 넣는 것이었다.
하지만 이를 위해서는 필수적으로 이중 for문이 들어가게 되고 문제의 조건인 시간 복잡도 O(N)을 만족할 수 없게 되어
시간 초과가 나오게 되었다.
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
arr = []
for i in range(len(nums)):
num = 1
for j in range(len(nums)):
if i == j:
continue
else:
num *= nums[j]
arr.append(num)
return arr
📌 두 번째 풀이
그렇다면 어떻게 이중 for문 즉 O(N^2)이 아닌 O(N)에 풀 수 있을까?
방법은 자기 자신을 제외하고 왼쪽의 모든 곱과 오른쪽의 모든 곱을 구해 그 둘을 곱하는 것이다.
우선 왼쪽에 있는 모든 곱을 out이라는 리스트에 넣어보자
코드는 다음과 같다.
out = []
p = 1
for i in range(0, len(nums)):
out.append(p)
p = p * nums[i]
여기서 중요한 점은 새롭게 p를 갱신해 주는 부분 앞에 out.append를 넣어 주어 첫 번째 값 곱셈은 항상 1이며 마지막 값 곱셈을 항상 제외하여 주는 것이다.
이제 오른쪽에 있는 곱은 기존에 있는 out(왼쪽에 있는 곱이 들어간 리스트)에 곱해주자
코드는 다음과 같다.
p = 1
for i in range(len(nums)-1, -1, -1):
out[i] *= p
p *= nums[i]
우선 P를 다시 1로 초기화해주고 for문을 첫 번째를 len(nums) - 1에서 시작해 0까지 (-1의 전) -1씩 내려가는 반복문을 돌려 기존의 out배열의 i번째와 곱해준다.
이를 이해하기 쉽게 그림으로 나타내면 다음과 같다.
nums = [1, 2, 3, 4]
nums = [-1, 1, 0, -3, 3]
최종 코드
class Solution:
def productExceptSelf(self, nums: List[int]) -> List[int]:
out = []
p = 1
# 왼쪽 곱셈
for i in range(0, len(nums)):
out.append(p)
p = p * nums[i]
p = 1
# 오른쪽 곱셈
for i in range(len(nums)-1, -1, -1):
out[i] *= p
p *= nums[i]
return out
'Algorithm' 카테고리의 다른 글
백준 알고리즘 파이썬(Python) 1009번 분산처리 (0) | 2022.01.05 |
---|---|
리트코드(LeetCode) 561번 배열 파티션(Array Partition) (0) | 2021.09.27 |
백준 알고리즘 파이썬(Python) 1940번 주몽 (0) | 2021.09.25 |
리트코드(LeetCode) 15번 세 수의 합(3 Sum) (0) | 2021.09.25 |
백준 알고리즘 파이썬(Python) 14719번 빗물 (0) | 2021.09.25 |