ALGORITHM/Java algorithm

[JAVA][LeetCode] #238. Product of Array Except Self | Arrays | Medium |

호이호이호잇 2024. 4. 26. 19:00
728x90
반응형

 문제 / 예제 / 제한 조건 :

 

처음에 문제 보자마자 엄청 쉬워보였다.


# 풀이 1

내가 생각했던 방식은 [1,2,3,4] 가 있다면

이 값을 모두 곱해둔 값을 하나 가지고 있고 -> 24

result를 저장 할 때, nums[i]로 나누어서 저장하면 된다고 생각했다.

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int[] results = new int[nums.length];

        int allMultipleValue = 1;
        for (int num : nums) {
            allMultipleValue *= num;
        }

        for (int i = 0; i < nums.length; i++) {
            results[i] = nums[i] == 0 ? 0 : (allMultipleValue / nums[i]);
        }

        return results;
    }
}
Time complexity : O(n)
Space complexity : O(n)

그래서 이렇게 나왔는데, 0이 중간에 있는 두 번째 예시의 경우 적합하지 않은 방식이였다.

 


 

그래서 생각해낸 두번째 방법

# 풀이 2

전체적인 플로우는 1번 풀이법과 같으나

nums의 멤버로 01개만 포함되어 있는 경우 / 2개 이상 포함되어 있는 경우 / 없는 경우 로 나누어서 생각했다.

 

왜냐하면

1. 0이 1개 포함되어 있는 경우, 0의 인덱스를 제외한 나머지 인덱스 들의 결과 값은 0이 된다.

2. 0이 2개 이상 포함되어 있는 경우, 결과 값은 모두 0

3. 0이 1개도 포함되어 있지 않은 경우, 풀이 1의 방법을 그대로 사용하면 된다.

 

그래서 나는 위의 경우를 zeroIndex의 값을 달리해주는 것으로 구분하였다.

1. 0이 1개 포함되어 있는 경우, zeroIndex = 0이 위치한 index

2. 0이 2개 이상 포함되어 있는 경우, zeroIndex = -99

3. 0이 1개도 포함되어 있지 않은 경우, zeroIndex = -1

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int zeroIndex = -1; // 0's count == 1 -> index / 0's count > 1 -> -99 / 0's count == 0 -> -1

        int allMultipleValue = 1;
        for (int i = 0; i < nums.length; i++) {
            if (nums[i] == 0) {
                zeroIndex = zeroIndex == -1 ? i : -99;
            } else {
                allMultipleValue *= nums[i];
            }
        }

        for (int i = 0; i < nums.length; i++) {
            if(zeroIndex == -99) {
                nums[i] = 0;
            } else if(zeroIndex == -1){
                nums[i] = allMultipleValue / nums[i];
            } else {
                if(zeroIndex == i) {
                    nums[i] = allMultipleValue;
                } else {
                    nums[i] = 0;
                }
            }
        }

        return nums;
    }
}
Time complexity : O(n) 
Space complexity : O(1)

통과를 하긴 했으나 문제 풀이가 깔끔한 것 같지 않아서 유튜브를 검색


유튜브에서 풀이 접근 하는 방법까지만 보았다.

https://www.youtube.com/watch?v=bNvIQI2wAjk

 

완전 유레카!!

인덱스 앞 뒤를 따로 계산해주고 그것을 곱해주면 된다니 !!!!

 

풀이 3

nums 1 2 3 4

가 있는 경우

prefix        
suffix        

이렇게 두 개의 배열을 만들어서 각 인덱스 전(prefix) 후(suffix) 의 값을 곱한 결과를 넣는다.

 

예를 들어

prefix의 경우

prefix 1      

시작 부분은 nums[0] 전에 곱할 숫자가 없어서 1

prefix 1 1    

nums[1] 전의 수 : nums[0] 이므로 nums[0]

prefix 1 1 2  

nums[2] 전의 수 :  nums[0] * nums[1] = 2

prefix 1 1 2 6

nums[3] 전의 수 :  nums[0] * nums[1] *  nums[2] = 6

이 것을 다르게 표현하면 prefix[2] * nums[2] 가 된다.

 

따라서 prefix[i] = prefix[i-1] * nums[i-1]이 된다!

 

suffix 의 경우, 뒤부터 시작

suffix       1

시작 부분은 nums[3] 뒤에 곱할 숫자가 없어서 1

suffix     4 1

nums[2] 뒤의 수 : nums[3] 이므로 nums[3]

suffix   12 4 1

nums[1] 뒤의 수 :  nums[3] * nums[2] = 12

suffix 24 12 4 1

nums[0] 뒤의 수 :  nums[3] * nums[2] *  nums[1] = 24

이 것을 다르게 표현하면 suffix[1] * nums[0] 가 된다.

 

따라서 suffix[i] = suffix[i+1] * nums[i+1]이 된다!

 

그리고 이제 결과 값은, 각각의 값을 곱하면 된다.

prefix 1 2 6
suffix 24 12 4 1
result 24 12 8 6

 

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int[] prefix = new int[nums.length];
        int[] suffix = new int[nums.length];
        int[] result = new int[nums.length];

        // prefix
        prefix[0] = 1;
        for(int i=1; i<nums.length; i++) {
            prefix[i] = prefix[i-1] * nums[i-1];
        }

        // suffix
        suffix[nums.length-1] = 1;
        for(int i=nums.length-2; i>=0; i--) {
            suffix[i] = suffix[i+1] * nums[i+1];
        }

        for(int i=0; i<nums.length; i++) {
            result[i] = prefix[i] * suffix[i];
        }

        return result;
    }
}
Time complexity : O(n)
Space complexity : O(n)


이 방식보다 빠를 수 있을까 ? 생각하다가

한 번에 해보자 ! 생각했다

 

풀이 4

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int[] result = new int[nums.length];

        // prefix
        result[0] = 1;
        for(int i=1; i<n; i++) {
            result[i] = result[i-1] * nums[i-1];
        }

        // suffix & result
        int suffixMultiple = 1;
        for(int i=n - 1; i>=0; i--) {
            result[i] *= suffixMultiple;
            suffixMultiple *= nums[i];
        }

        return result;
    }
}
Time complexity : O(n)
Space complexity : O(n)

 

신기하다 유레카 !~!

728x90
반응형