[Leetcode] Weekly Contest 237 후기 및 풀이
in Problem Solving on Leetcode
Contest : Leetcode - Weekly Contest 237
Solution code : Github
Weekly Contest 237 후기
오랜만에 4문제 모두 PASS 했습니다. 개인적으로는 3번 문제가 신경쓸 부분이 좀 있어서 고민하는데 시간이 좀 걸렸고, 4번 문제가 오히려 난이도가 더 낮았던 것 같습니다. 1번은 단순 문자열 처리, 2번은 정렬, 3번은 힙 문제였으며 4번은 비트 연산에 대한 생각을 조금 해보면 풀 수 있었습니다.
문제 1. Check if the Sentence Is Pangram
문제
소문자로만 이루어진 문자열 sentence
가 주어집니다. sentence
에서 소문자 알파벳 26개가 모두 최소 한번씩은 포함되어 있는 문자열인지 판단하는 문제입니다.
제약 조건:
1 <= sentence.length <= 1000
풀이
소문자 알파벳 26개가 모두 문자열에 포함되어 있는지 확인하면 됩니다.
- Time : O(N) [N:
sentence.length
] - Space : O(1)
- Tag :
String
C++
class Solution {
public:
bool checkIfPangram(string sentence) {
int c[26] = { 0, };
for (int i = 0; i < sentence.size(); i++)
c[sentence[i] - 'a'] = 1;
int sum = 0;
for (int i = 0; i < 26; i++)
sum += c[i];
return sum == 26;
}
};
Python
class Solution(object):
def checkIfPangram(self, sentence):
c = [0]*26
for ch in list(sentence):
c[ord(ch) - ord('a')] = 1
return True if sum(c) == 26 else False
문제 2. Maximum Ice Cream Bars
문제
n개의 정수형 배열인 costs
와 정수 값 coins
가 주어집니다. costs
는 n개의 아이스크림 가격을 의미하며 주어진 coins
으로 아이스크림을 구매할 수 있는 최대 개수를 구하는 문제입니다.
제약 조건:
costs.length == n
1 <= n <= 10^5
1 <= costs[i] <= 10^5
1 <= coins <= 10^8
풀이
아이스크림 가격을 오름차순으로 정렬한 후에 가장 저렴한 것부터 구매하면 됩니다.
- Time : O(NlogN) [N :
costs.length
] - Space : O(1)
- Tag :
Greedy
,Sort
C++
class Solution {
public:
int maxIceCream(vector<int>& costs, int coins) {
sort(costs.begin(), costs.end());
int res = 0;
for (int i = 0; i < costs.size(); i++)
{
if (coins < costs[i]) break;
coins -= costs[i];
res++;
}
return res;
}
};
Python
class Solution(object):
def maxIceCream(self, costs, coins):
res = 0
for x in sorted(costs):
if(x > coins):
break
coins -= x
res += 1
return res
문제 3. Single-Threaded CPU
문제
N개의 작업이 주어집니다. 이 작업은 tasks[i] = [enqueueTime(i), processingTime(i)]
형태로 주어지며 모두 정수값입니다. enqueueTime
은 이 시간부터 작업을 시작할 수 있고, processingTime
은 작업을 마치기 위해 필요한 소요시간을 의미합니다.
이때 아래와 같은 single-threaded CPU 를 만들어야 합니다.
- CPU가 Idle 상태에서 작업할
task
가 없으면 아무런 처리를 하지 않습니다. - CPU가 Idle 상태에서 작업할 수 있는
tasks
중에서 가장 작은processing Time
를 가진task
부터 처리합니다. - 하나의
task
를 시작하면 작업이 끝날때까지 그 작업만 처리합니다. - CPU가
task
를 완료한 즉시 바로 다른task
를 시작할 수 있습니다.
제약 조건:
tasks.length == n
1 <= n <= 10^5
1 <= enqueueTime(i), processingTime(i) <= 10^9
풀이
CPU가 현재 시간 기준으로 작업가능한 task
를 파악하기 위해 enqueueTime
순으로 정렬합니다. 단 작업번호를 출력해야하기 때문에 작업번호를 넣습니다.
또한 작업 가능한 tasks
에서 processingTime
이 가장 작은 작업부터 진행해야 되기 때문에 이를 Min-heap 으로 구성합니다.
이제 우선순위가 가장 높은 작업을 하나씩 처리하면서 현재시간을 업데이트하기만 하면 됩니다. 추가로 현재 시간에 하나도 작업할 수 없는 경우에는 바로 다음 enqueueTime
으로 이동해야 하는 예외처리를 해주어야 합니다.
- Time : O(NlogN), [N :
tasks.length
] - Space : O(N)
- Tag :
Heap
C++
class Solution {
struct task
{
int i;
int pTime;
bool operator < (const task& rhs) const
{
if (pTime == rhs.pTime) return i > rhs.i;
else return pTime > rhs.pTime;
}
};
public:
vector<int> getOrder(vector<vector<int>>& tasks) {
for (int i = 0; i < tasks.size(); i++) tasks[i].push_back(i);
sort(tasks.begin(), tasks.end());
priority_queue<task> available;
vector<int> res;
long long cT = 1, i = 0;
while (available.size() != 0 || i < tasks.size())
{
while (i < tasks.size() && (long long)tasks[i][0] <= cT)
{
available.push({ tasks[i][2], tasks[i][1] });
i++;
}
if (available.size() == 0)
{
cT = tasks[i][0];
continue;
}
task top = available.top(); available.pop();
res.push_back(top.i);
cT += top.pTime;
}
return res;
}
};
Python
class Solution(object):
def getOrder(self, tasks):
tasks = sorted([(v[0], v[1], i) for i, v in enumerate(tasks)])
available = []
res = []
cT, i = 1, 0
while len(available) != 0 or i < len(tasks):
while i < len(tasks) and tasks[i][0] <= cT:
heapq.heappush(available, (tasks[i][1], tasks[i][2]))
i += 1
if len(available) == 0:
cT = tasks[i][0]
continue
pT, idx = heapq.heappop(available)
res.append(idx)
cT += pT
return res
문제 4. Find XOR Sum of All Pairs Bitwise AND
문제
2개의 정수형 배열 arr1
과 arr2
가 주어집니다. 모든 가능한 (i, j) 쌍에 대하여 arr1[i] & arr2[j]
인 값으로 구성된 배열을 만듭니다. 즉 arr1.length * arr2.length
크기의 배열이 만들어 집니다. 이때 이 생성된 배열의 XOR sum
값을 구하는 문제입니다.
여기서 XOR sum
은 배열의 모든 element를 bitwise-XOR
한 값입니다.
제약 조건:
1 <= arr1.length, arr2.length <= 10^5
0 <= arr1[i], arr2[j] <= 10^9
풀이
먼저 a1 & (b1^b2) = (a1&b1) ^ (a1&b2)
임을 알 수 있습니다. 조금 더 확장하면 (a1^a2) & (b1^b2) = (a1^b1) & (a1^b2) & (a2^b1) & (a2^b2)
입니다.
문제에서 구하고자 하는 것은 (xorsum of arr1) AND (xorsum of arr2)
와 같은 값임을 알 수 있습니다.
- Time : O(N + M) [N :
arr1.length
, M:arr2.length
] - Space : O(1)
- Tag :
Bit Manipulation
Greedy
C++
class Solution {
public:
int getXORSum(vector<int>& arr1, vector<int>& arr2) {
int xor1 = 0, xor2 = 0;
for (int i = 0; i < arr1.size(); i++)
xor1 ^= arr1[i];
for (int i = 0; i < arr2.size(); i++)
xor2 ^= arr2[i];
return xor1 & xor2;
}
};
Python
class Solution(object):
def getXORSum(self, arr1, arr2):
xor1 = xor2 = 0
for x in arr1:
xor1 ^= x;
for y in arr2:
xor2 ^= y
return xor1 & xor2