Skip to content

Commit 9c068d6

Browse files
committed
Product of Array Except Self - space complexity O(1)
1 parent 65e2454 commit 9c068d6

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

product-of-array-except-self/forest000014.java

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
/*
2-
runtime 12 ms, beats 4.87%
3-
memory 60.49 MB, beats 5.89%
2+
runtime 8 ms, beats 4.87%
3+
memory 55.44 MB, beats 54.17%
44
55
time complexity: O(n)
66
- nums 각각의 원소를 소인수분해 : O(10 * n) = O(n)
7-
- ans[] 배열 계산 : O(n)
7+
- ans[] 배열 계산 : O(10 * n)
8+
- i, j, k의 3중 for-loop가 O(n * 10 * 4) 처럼 보일 수 있는데요(10은 소인수 분해 base의 개수, 4는 power중 최대값),
9+
- 실제로는 k가 큰 경우에는 j-loop가 일찍 끝나고 (예컨대 nums[i] = 2^4 인 경우에는, base가 2에서 끝나니 j-loop가 j=1에서 끝남)
10+
- j가 큰 경우에는 k-loop가 일찍 끝나므로 (예컨대 num[i] = 29인 경우에는, k-loop가 1에서 끝남)
11+
- 최악의 경우에 O(n * 10) 정도로 보는 게 타당하다고 생각합니다.
812
9-
space complexity: O(n)
10-
- 2차원 배열(n * 10) - powers : O(n)
11-
- 1차원 배열들(n) - minuses, ans: O(n)
13+
space complexity: O(1)
1214
1315
[풀이]
1416
나눗셈이 금지되어 있기 때문에, 최대한 곱할 수 있는 만큼을 미리 곱해놓고, i번째 원소마다 부족한 부분만큼을 나중에 채워 넣어 곱해주는 방식으로 접근했습니다.
@@ -17,6 +19,7 @@
1719
1820
이 풀이에서 아쉬운 점이 여전히 있습니다. 시간 복잡도를 따지면 O(10*n) = O(n)이니 문제의 조건을 맞췄다고 할 수도 있겠지만, 상수가 좀 크다는 점이 마음에 걸리네요.
1921
(for (int j = 0; j < 10 && abs > 1; j++) <--- 여기에서 abs == 1이 되면 for-loop를 빠져나가게 했지만, nums[i]가 모두 29로 차있는 edge case라면 10*n을 꽉 채우게 되니까요.)
22+
그래도 어쨌든 문제의 조건을 최대한 활용해서 시도해볼만한 접근이라고 생각합니다.
2023
2124
이 풀이 말고도, nums[]를 2개로 나눈 블럭, 4개로 나눈 블럭, 8개로 나눈 블럭, ... 이런 식으로 사이즈 별로 블럭을 나눠두고, 각각의 블럭 내부의 곱을 미리 계산해두는 방식도 생각해보았습니다. 이러면 시간 복잡도와 공간 복잡도가 모두 O(nlogn)이 나올 것 같습니다. (사실 이 풀이를 가장 처음에 떠올렸습니다만, O(n)으로 줄이는 고민을 하다가 현재 제출한 풀이를 떠올리고서는 이 풀이는 구현을 안 했습니다. 시간이 되면 이렇게도 풀어보고, 좀 더 디벨롭을 해봐야겠네요.)
2225
*/
@@ -25,12 +28,9 @@ public int[] productExceptSelf(int[] nums) {
2528
int n = nums.length;
2629

2730
int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
28-
int[][] powers = new int[n][10];
2931
int[] sumPowers = new int[10];
3032
int[] maxPowers = new int[10];
3133

32-
boolean[] minuses = new boolean[n];
33-
3434
int base = 1;
3535

3636
int[] ans = new int[n];
@@ -56,13 +56,11 @@ public int[] productExceptSelf(int[] nums) {
5656
} else {
5757
abs = -nums[i];
5858
base = -base;
59-
minuses[i] = true;
6059
}
6160

6261
for (int j = 0; j < 10 && abs > 1; j++) {
6362
int curPower = 0;
6463
while (abs % primes[j] == 0) {
65-
powers[i][j]++;
6664
sumPowers[j]++;
6765
curPower++;
6866
abs /= primes[j];
@@ -82,11 +80,17 @@ public int[] productExceptSelf(int[] nums) {
8280
for (int i = 0; i < n; i++) {
8381
ans[i] = base;
8482
for (int j = 0; j < 10; j++) {
85-
for (int k = 0; k < maxPowers[j] - powers[i][j]; k++) {
83+
int tmp = nums[i];
84+
int power = 0;
85+
while (tmp % primes[j] == 0) {
86+
power++;
87+
tmp /= primes[j];
88+
}
89+
for (int k = 0; k < maxPowers[j] - power; k++) {
8690
ans[i] *= primes[j];
8791
}
8892
}
89-
if (minuses[i]) {
93+
if (nums[i] < 0) {
9094
ans[i] = -ans[i];
9195
}
9296
}

0 commit comments

Comments
 (0)