Skip to content

[Algorithm] 두 큐 합 같게 만들기 #12

Description

@hwangJi-dev

📌 TODO

  • 문제 풀이
  • 정리

🎢 두 큐 합 같게 만들기

💬 문제

https://school.programmers.co.kr/learn/courses/30/lessons/118667#


💬 Idea

  1. 첫번째 아이디어
    1. 배열을 queue로 사용해서 queue1, queue2의 각 합계를 비교한다
    2. 합계가 더 큰쪽에서 작은쪽으로 원소를 이동시킨다
  2. 두번째 아이디어
    1. 투포인터를 사용한다.
    2. 원리는 1과 같다.

💬 풀이

1️⃣ <1차 풀이>

func solution(_ queue1:[Int], _ queue2:[Int])->Int{varqueue1= queue1
varqueue2= queue2
varans=0while queue1.reduce(0,+)!= queue2.reduce(0,+){letqueue1sum= queue1.reduce(0,+)letqueue2sum= queue2.reduce(0,+)if queue1sum >= queue2sum {
queue2.append(queue1.removeFirst())
ans +=1}else{
queue1.append(queue2.removeFirst())
ans +=1}
// 탈출조건
if queue1.isEmpty || queue2.isEmpty {return-1}}return ans
}

정확성 56.7 / 100.0

2️⃣ <2차 풀이>
-> 반복문 내에서 고차함수 reduce를 제외하여 sum(총합)을 계산하는 원리를 변경했다. → 시간초과 일부 해결

func solution(_ queue1:[Int], _ queue2:[Int])->Int{varqueue1= queue1
varqueue2= queue2
varqueue1sum= queue1.reduce(0,+)varqueue2sum= queue2.reduce(0,+)varans=0while queue1sum != queue2sum {if queue1sum >= queue2sum {letremove= queue1.removeFirst()
queue2.append(remove)
queue1sum -= remove
queue2sum += remove
}else{letremove= queue2.removeFirst()
queue1.append(remove)
queue2sum -= remove
queue1sum += remove
}
ans +=1
// 탈출조건
if queue1.isEmpty || queue2.isEmpty {return-1}}return ans
}

합계: 83.3 / 100.0

3️⃣ <3차 풀이>

func solution(_ queue1:[Int], _ queue2:[Int])->Int{varmaxCnt= queue1.count + queue2.count
varqueue1= queue1
varqueue2= queue2
varqueue1sum= queue1.reduce(0,+)varqueue2sum= queue2.reduce(0,+)varans=0while queue1sum != queue2sum {if queue1sum >= queue2sum {letremove= queue1.removeFirst()
queue2.append(remove)
queue1sum -= remove
queue2sum += remove
}else{letremove= queue2.removeFirst()
queue1.append(remove)
queue2sum -= remove
queue1sum += remove
}
ans +=1
// 탈출조건
if queue1.isEmpty || queue2.isEmpty || ans > maxCnt {return-1}}return ans
}

합계: 86.7 / 100.0

직접 큐(Queue) 자료구조를 이용하지 않고 단순히 배열을 큐로 사용하면 0번 원소를 지우는 과정에서 시간 초과가 발생할 수도 있다….

4️⃣ <4차 풀이 - 풀이방법 투포인터로 변경>

func solution(queue1:[Int], queue2:[Int])->Int{varmaxCnt= queue1.count *4varqueue= queue1 + queue2
varpointer=(0, queue1.count)varqueue1sum= queue1.reduce(0,+)varqueue2sum= queue2.reduce(0,+)varans=0while queue1sum != queue2sum {if queue1sum >= queue2sum {
queue1sum -=queue[pointer.0]
queue2sum +=queue[pointer.0]
pointer.0+= pointer.0+1> queue.count -1?0:1}else{
queue1sum +=queue[pointer.1]
queue2sum -=queue[pointer.1]
pointer.1+= pointer.1+1> queue.count -1?0:1}
ans +=1
// 탈출조건
if ans > maxCnt {return-1}}return ans
}

💬 알게된 것

  • queue를 구현하기 위해 단순 배열을 이용하여 dequeue를 할 때 removeFirst는 시간이 많이 걸린다.

    • 이유?
      • Swift는 Queue가 구현이 되어 있지 않아서, 직접 배열로 구현을 해야함.
  • maxCnt가 4배인 이유

    • 이때, 전체 배열의 길이가 2n이므로, 한 포인터 당 최대 2n번의 이동이 필요합니다. 따라서, 총 4n만큼의 작업을 수행한 뒤에도 두 큐의 합을 같게 만들지 못했다면 그 이후에는 이미 탐색했던 구간을 다시 탐색하는 것이므로 의미가 없습니다. 이 경우에는 -1을 반환

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions