https://school.programmers.co.kr/learn/courses/30/lessons/42626#qna
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
참고로 저번기수때 풀었던 문제였다!
https://usowelcome.tistory.com/5
99클럽 코테 스터디 2일차 TIL : heap - 더 맵게 (미들러)
heap이용해서 스코빌지수 K이상으로 만들기-> min heap이용해서 push, pop을 반복해 K이상인 원소가 루트에 있는지 계속 확인해주면 됐다.C++에서는 라이브러리에서 make_heap()함수를 지원한다.make_heap(v.b
usowelcome.tistory.com
근데.... 효율성문제때문에 또 문제가 많았다!ㅎㅎ...
이전코드와 지금코드를 비교해봐야겠다ㅎㅎ
바로 푼것 -> 효율성에서 막힘
검색을 통해 다른방법을 생각 -> 통과!
이전에 만들었던 코드 -> 왜인지 모르지만 통과
이런 흐름이었다ㅎㅎ
[첫번째 시도] : 효율성에서 망함
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int solution(vector<int> scoville, int K) {
int answer = 0;
make_heap(scoville.begin(), scoville.end(), greater<>());
while(true){
if(scoville[0] >= K){
break;
}
if(scoville.size() < 2){
return -1;
}
int a1 = scoville[0];
pop_heap(scoville.begin(), scoville.end(), greater<>());
scoville.pop_back();
int a2 = scoville[0];
pop_heap(scoville.begin(), scoville.end(), greater<>());
scoville.pop_back();
int newsco = a1 + (a2 * 2);
scoville.push_back(newsco);
make_heap(scoville.begin(), scoville.end(), greater<>());
answer++;
}
return answer;
}
테스트케이스는 전부 통과하는데 효율성에서 막힌 코드이다.
사실 왜 문제인지 모르겠다...
heap도 잘 썼는데...... 매번 정렬해서? 근데 min heap을 유지하려면 저렇게 해야한다.,,
[두번째 시도] priority_que를 도입하자!
우선순위큐를 사용하면 효율성테스트를 통과한다는 글을 보았다.
근데,,, c++에서 우선순위큐는 힙으로 구현되어있는걸로 알고있는데??
그래도 일단 시도해봤다
근데...
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
int solution(vector<int> scoville, int K) {
int answer = 0;
priority_queue<int, vector<int>, greater<int>> myque(scoville.begin(), scoville.end());
while(true){
int a1 = myque.top();
if(a1 >= K){
break;
}
if(myque.size() < 2){
return -1;
}
myque.pop();
int a2 = myque.top();
myque.pop();
int newsco = a1 + (a2 * 2);
myque.push(newsco);
answer++;
}
return answer;
}
엥 통과했디;;;;;;;;;;;
왜???????
https://usowelcome.tistory.com/61
c++ priority_queue vs heap
라이브러리에 들어있다. -> que인데 우선순위가 있는 (정렬되어 있는) 큐라고 생각하면 된다. 사용하는 함수들은 기본 queue와 같다(push, pop... 등등)=> 근데 제일 끝 원소를 가져올 때 그냥 queue는 fr
usowelcome.tistory.com
바로바로 c++에서 우선순위큐와 힙의 시간복잡도에서 차이가 나기 때문이었다!
[세번째 시도] 근데 heap으로도 통과 되는데...
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <numeric>
using namespace std;
int solution(vector<int> scoville, int K) {
int answer = 0;
make_heap(scoville.begin(), scoville.end(),greater<>{});
while(true){
if(scoville[0] >= K){
break;
}
if(scoville.size() < 2){
answer = -1;
break;
}
int min1 = scoville[0];
pop_heap(scoville.begin(), scoville.end(),greater<>{});
scoville.pop_back();
int min2 = scoville[0];
pop_heap(scoville.begin(), scoville.end(),greater<>{});
scoville.pop_back();
int newint = min1 + (min2 * 2);
scoville.push_back(newint);
push_heap(scoville.begin(), scoville.end(),greater<>{});
answer++;
}
return answer;
}
이건 예전에 풀었던 코드를 그대로 가져왔다.
내가 첫번째에 작성했던것과 차이가 없어보이는데,,
처음 찾은 차이점 : greater<>() vs greater<>{}
=> 근데 이건 문제가 아니었다. 그냥 c++11때 추가된 중괄호 초기화 문법이었고, 기능에 차이는 없다.
실제로 세번째코드의 {}를 ()로 바꿔서 실행했을때도 문제는 없었다.
두번째 찾은 차이점 : if(scovile.size() < 2)에서 처리의 차이
=> 그냥 return을 하는것과, answer를 바꾸고 break를 하는 차이였지만,,,
이것도 문제는 아니었다.
진짜 문제점 : make_heap vs push_heap
while문의 마지막부분에, 새로운 스코빌지수를 계산해서 heap에 넣어줄 때 차이가 있었고 이게 문제였다!
문제코드는 make_heap을 해주었고, 세번째코드는 push_heap을 해주었다,
https://en.cppreference.com/w/cpp/algorithm/push_heap
std::push_heap - cppreference.com
template< class RandomIt > void push_heap( RandomIt first, RandomIt last ); (1) (constexpr since C++20) template< class RandomIt, class Compare > void push_heap( RandomIt first, RandomIt last, Compare comp ); (2) (constexpr since C++20) Inserts the element
en.cppreference.com
push_heap은 logn의 시간복잡도를 가진다 (make_heap이 n의 시간복잡도를 가지는것과 비교됨)
=> 즉 push_heap을 했어야 했다.
make_heap을 해주면 while전체의 시간복잡도는 n^2이 되는데
push_heap을 해주면 whle전체의 시간복잡도는 nlogn!!
그러니까 두번째에서 우선순위큐로 해결됐던것도, push_heap의 차이때문이었던것 같다
(queue vs heap 잘 구분하기!)
https://usowelcome.tistory.com/8
우선순위큐
큐 : 먼저 들어온게 먼저 나감 (FIFO)우선순위큐 : priority가 높은게 먼저나감 (순서보다 priority가 먼저 고려됨) -> 우선순위큐를 구현하는 방법이 heap인것! (동작만 잘 작동하면 뭐로 구현하든 상관
usowelcome.tistory.com
https://usowelcome.tistory.com/4
힙(heap)
이진트리 -> level간 숫자의 크기순서가 유지되는 자료구조 1. min heap : 상위 레벨(위쪽)에 더 작은 숫자 (더 작은 우선순위를 가진 데이터)가 있음2. max heap : 상위 레벨(위쪽)에 더 큰 숫자 (더 큰
usowelcome.tistory.com
큐를 구현하는 방법이 힙인것! (따로 생각하지 말자^^...)
에휴 한번 풀어본문제였는데...^^;;;;;
백준 : 11279 - 최대힙 (0) | 2024.07.31 |
---|---|
99클럽 코테 스터디 8일차 TIL : 이중우선순위큐 (0) | 2024.07.31 |
99클럽 코테 스터디 6일차 TIL : 기능개발 (0) | 2024.07.29 |
[코드트리 조별과제] : 2주차 (0) | 2024.07.28 |
7/26 TIL : DFS (0) | 2024.07.27 |