hyelie
hyelie
Hyeil Jeong
       
글쓰기    관리    수식입력
  • 전체보기 (495)
    • PS (283)
      • Algorithm (28)
      • PS Log (244)
      • Contest (6)
      • Tips (5)
    • Development (52)
      • Java (14)
      • Spring (23)
      • SQL (2)
      • Node.js (2)
      • Socket.io (3)
      • Study (4)
      • Utils (4)
    • DevOps (36)
      • Git (5)
      • Docker (4)
      • Kubernetes (2)
      • GCP (3)
      • Environment Set Up (8)
      • Tutorial (12)
      • Figma (2)
    • CS (74)
      • OOP (7)
      • OS (24)
      • DB (2)
      • Network (24)
      • Architecture (0)
      • Security (2)
      • Software Design (0)
      • Parallel Computing (15)
    • Project (15)
      • Project N2T (5)
      • Project ASG (0)
      • Project Meerkat (1)
      • Model Checking (7)
      • Ideas (2)
    • 내가 하고싶은 것! (34)
      • Plan (16)
      • Software Maestro (10)
      • 취준 (8)
hELLO · Designed By 정상우.
hyelie

hyelie

PS/PS Log

23.02.24. 풀었던 문제들

리트코드 daily challenge - 1675. Minimize Deviation in Array

 주어진 array에서 짝수는 2로 나눌 수 있고, 홀수는 2배할 수 있을 때, [최대값 - 최소값]의 결과를 최소화하는 문제.

 이것저것 접근하다가 다음과 같이 접근했다.

  • 홀수를 2배하면 짝수가 되기 때문에 모든 경우의 수에서 수를 2배로 하는 것은 단 1번이다.(더 이상 커질 수 없다.)
  • 나누는 것은 홀수가 될 때 까지 나눌 수 있다.
  • 이것에 착안해서 한쪽방향으로만 연산하고자 했다.

 증명은 다음과 같다.

deviation을 줄이기 위해서는 max값을 줄이거나, min값을 늘려야 한다.
모든 홀수를 2배로 해버린다면, min값을 더 늘일 수 없다.
따라서 max값을 줄이는 연산만 남게 된다.
max값을 줄일 수 있을 때까지 줄이면 그것이 min deviatino이다.
 - 홀수에 2를 곱했으며, 어차피 2로 나누면 원래 수로 돌아온다. 필요 시 다시 홀수가 될 것이다.

 

 코드는 다음과 같다.

// runtime 352ms (beats 84.75%)
// memory 89MB (beats 43.22%)

class Solution {
public:
    int minimumDeviation(vector<int>& nums) {
        set<int> s;
        for(int num : nums){
            s.insert(num & 1 ? num * 2 : num);
        }

        if(s.size() == 1) return 0;
    
        int answer = *s.rbegin() - *s.begin();
        while(!(*s.rbegin() & 1)){
            int last = *s.rbegin();
            s.erase(last);
            s.insert(last / 2);
            if(s.size() == 1) return 0;
            answer = min(answer, *s.rbegin() - *s.begin());
        }
        return answer;
    }
};

 

 시간복잡도는 O(n * logm * logn)이다. set에서 element를 넣고, 꺼내는 데 O(logn)이 걸리며, 어떤 element를 더 이상 줄일 수 없을 때까지 m번 연산한다고 했을 때, 이건 약 30이다.(2의 거듭제곱을 약 30번 줄일 수 있음) worst case 모든 element에 대해 이 연산을 할 수 있기 때문에 O(n * logm * logn)이다. 사실상 logm이 worst 30이기 때문에 O(nlogn)이다.

 공간복잡도는 O(n)이다. set에 n만큼 들어가기 때문.

 

 

 

 

 

 

 

 

 

저작자표시 (새창열림)

'PS > PS Log' 카테고리의 다른 글

23.02.26. 풀었던 문제들  (0) 2023.02.26
23.02.25. 풀었던 문제들  (0) 2023.02.25
23.02.23. 풀었던 문제들  (0) 2023.02.23
23.02.22. 풀었던 문제들  (0) 2023.02.22
23.02.21. 풀었던 문제들  (0) 2023.02.21
    hyelie
    hyelie

    티스토리툴바