Leetcode刷題 2021.02.09
技術標籤:刷題
Leetcode刷題 2021.02.09
Leetcode992 K 個不同整數的子陣列
給定一個正整數陣列 A,如果 A 的某個子陣列中不同整數的個數恰好為 K,則稱 A 的這個連續、不一定不同的子陣列為好子陣列。
(例如,[1,2,3,1,2] 中有 3 個不同的整數:1,2,以及 3。)
返回 A 中好子陣列的數目。
明天要回家過年了,不知道有沒有時間更新部落格了,還是希望部落格連續更新不斷吧。
今天的每日一題,困難題考查的的技巧方面就比較多了,如果沒有一定的演算法訓練的話還真的是做不出。其實就是把中等題改了一下,但是怎麼想得到的話就是另一回事了。
class Solution {
public int subarraysWithKDistinct(int[] A, int K) {
//恰好k個等於最多k個減去最多k - 1個。
return helper(A, K) - helper(A, K - 1);
}
//至多包含k個不同整數的子陣列
private int helper(int[] A, int K){
int n = A.length;
int[] map = new int[n + 1];
int i = 0, j = 0, count = 0, res = 0;
while (j < n){
//增大右視窗,維護一個數組,記錄不同整數的個數
if (map[A[j]] == 0) count++;
map[A[j]]++;
//如果不滿足條件了,就縮小左視窗
while (count > K){
map[A[i]]--;
if (map[A[i]] == 0) count--;
i++;
}
//比如[1,2,1,2],i = 0, j = 3時,有4個滿足條件,即[2], [1,2], [2,1,2], [1,2,1,2]。就是以2為末尾的四個子陣列
res += j - i + 1;
j++;
}
return res;
}
}
Leetcode475 供暖器
冬季已經來臨。 你的任務是設計一個有固定加熱半徑的供暖器向所有房屋供暖。
在加熱器的加熱半徑範圍內的每個房屋都可以獲得供暖。
現在,給出位於一條水平線上的房屋 houses 和供暖器 heaters 的位置,請你找出並返回可以覆蓋所有房屋的最小加熱半徑。
說明:所有供暖器都遵循你的半徑標準,加熱的半徑也一樣。
求一個最小值,二分查詢的老套路了,不斷嘗試並且收縮區間,直到某一個最小值符合條件就行了。
class Solution {
public int findRadius(int[] houses, int[] heaters) {
int i = 0, j = 1_000_000_000;
//二分查詢模板,陣列沒說是有序的,先排序一下
Arrays.sort(houses);
Arrays.sort(heaters);
while (i < j){
int mid = i + (j - i) / 2;
if (helper(houses, heaters, mid)){
j = mid;
}else{
i = mid + 1;
}
}
return i;
}
private boolean helper(int[] houses, int[] heaters, int mid){
int index = 0, n = houses.length;
//看看每個供暖期是否都能覆蓋到所有的房屋
for(int i = 0; i < heaters.length; i++){
int left = heaters[i] - mid, right = heaters[i] + mid;
//如果在半徑內,就說明可以覆蓋
while (index < n && houses[index] >= left && houses[index] <= right){
index++;
}
if (index >= n) break;
//如果當前的房屋大於左邊的半徑,說明肯定不能覆蓋到了
if (houses[index] < left) return false;
}
return index < n ? false : true;
}
}
Leetcode1702 吃蘋果的最大數目
有一棵特殊的蘋果樹,一連 n 天,每天都可以長出若干個蘋果。在第 i 天,樹上會長出 apples[i] 個蘋果,這些蘋果將會在 days[i] 天后(也就是說,第 i + days[i] 天時)腐爛,變得無法食用。也可能有那麼幾天,樹上不會長出新的蘋果,此時用 apples[i] == 0 且 days[i] == 0 表示。
你打算每天 最多 吃一個蘋果來保證營養均衡。注意,你可以在這 n 天之後繼續吃蘋果。
給你兩個長度為 n 的整數陣列 days 和 apples ,返回你可以吃掉的蘋果的最大數目。
貪心的思想,就好比平時吃東西,肯定是先把離保質期最近的吃到。可以用優先佇列進行模擬,按過期時間從小到達排列,遍歷的時候如果吃光了或者過了保質期了就出隊。
class Solution {
public int eatenApples(int[] apples, int[] days) {
PriorityQueue<Node> queue = new PriorityQueue<>((x, y) -> (x.expire - y.expire));
int res = 0;
for(int i = 0; i < apples.length || !queue.isEmpty(); i++){
//如果有蘋果就加到佇列裡
if (i < apples.length && apples[i] != 0){
queue.offer(new Node(apples[i], i + days[i]));
}
//吃光了或者過了保質期了就出隊
while(!queue.isEmpty() && (queue.peek().expire<= i || queue.peek().num == 0)){
queue.poll();
}
//吃到離保質期最近的一個蘋果,同時吃掉的總數加1
if (!queue.isEmpty()){
queue.peek().num--;
res++;
}
}
return res;
}
//新建一個類,包含蘋果的數目和過期時間
class Node{
int num;
int expire;
public Node(int num, int expire){
this.num = num;
this.expire = expire;
}
}
}