LeetCode/Array

[Medium] 238. Product of Array Except Self (애플 코딩 테스트 문제)

Developer07 2022. 9. 8. 14:07

Leetcode 238번 문제는 정수로 채워진 array가 주어지고, 원래의 index에있는 값을 제외한 모든 index의 값을 곱한 값이 들어있는 array를 return하는 문제이다. 

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int product = 1;
        for(int i = 0; i < nums.length;i++){
            product *= nums[i];
        }
        int[] arr = new int[nums.length];
        
        for(int i = 0; i < nums.length;i++){
            if(nums[i] == 0){
            arr[i] = product;
            }
            else{
                 arr[i] = product / nums[i];
            }
        }
        return arr;   
    }
}

모든 값을 곱한 값에 array를 loop through하면서 원래의 값으로 나누면 되겠지만 이건 문제에도 나와있듯이 나누기는 금지돼있기 때문에 정답으로 쓸 수 없다.

class Solution {
    public int[] productExceptSelf(int[] nums) {
    int[] answer = new int[nums.length];
    for(int i = 0; i < nums.length;i++){
    int product = 1;
    }
    for(int j = 0; j < nums.length; j++){
    if(i!=j){
    product *= nums[j];
          }
        }
    answer[i] = product;
      }
    return answer;
    }
  }

위 풀이는 brute-force를 사용한 풀이인데 time complexity가 O(n)이 돼야 하기 때문에 이 풀이 역시 사용할 수 없다. 

 

#풀이

class Solution {
    public int[] productExceptSelf(int[] nums) {
      int[] left = new int[nums.length];
      int[] right = new int[nums.length];
      int[] answer = new int[nums.length];
     
        left[0] = 1;
        right[nums.length - 1]= 1;
        for(int i = 1; i < nums.length; i++){
            left[i] = nums[i-1] * left[i - 1];
            right[right.length -1 - i] = nums[nums.length - i] * right[right.length -i];
        }
        
        for(int i = 0; i < nums.length; i++){
            answer[i] = left[i] * right[i];
        }
        return answer;   
}
}

이 풀이는 left array와 right array를 만들어 left array의 맨 왼쪽을 1로 만들고, right array의 맨 오른쪽도 1로 만들고 시작한다. left array는 i  = 1에서 시작하고 nums array에 nums[i] 와 nums[i-1] 곱한 값으로 채워나간다. right array도 마찬가지로 nums.length - 1 에서 시작하고 1씩 index를 줄여나간다. 예를 들어 [1, 2, 3,4] 라는 array가있으면 left array는 [1, 1, 2, 6] (마지막 4는 제외) 이 되고,  right array는 [24, 12, 4, 1]  (첫번째 1 제외)이 된다. 마지막으로 left array와 right array를 상응하는 index끼리 곱해주면 [24, 12, 8, 6] 의 정답 array가 된다. 이 알고리즘의 time complexity는 O(2n) 이다.

# O(1) Space Complexity풀이

class Solution {
    public int[] productExceptSelf(int[] nums) {
    int[] answer = new int[nums.length];
        
    answer[0] = 1;
        for(int i=1; i < nums.length;i++){
            answer[i] = answer[i-1] * nums[i-1];
        }
        int right = 1;
        for(int i = nums.length - 1; i >= 0; i--){
            answer[i] *= right;
            right *= nums[i];
        }
        return answer;
}
}

위 풀이는 첫 번째 풀이와 똑같은 로직 이지만 array를 하나만 사용한 풀이이다. answer array하나만 사용하기 때문에 space complextiy가 O(1)이다. 문제에도 나왔듯이 output array는 extra memory로 치지 않는다.