[Leetcode Weekly Contest]266
[Leetcode]2062. 統計字串中的母音子字串
子字串 是字串中的一個連續(非空)的字元序列。
母音子字串 是 僅 由母音('a'、'e'、'i'、'o' 和 'u')組成的一個子字串,且必須包含 全部五種 母音。
給你一個字串 word ,統計並返回 word 中 母音子字串的數目 。
遍歷即可。
class Solution { public String Vowels = "aeiou"; public boolean isVowelString(String word,int i,int j) { Set<Character> wordSet = new HashSet<>(); for(int ind=i;ind<=j;++ind) { var ch = word.charAt(ind); if(Vowels.indexOf(ch)==-1) return false; wordSet.add(ch); } if(wordSet.size()==5) return true; return false; } public int countVowelSubstrings(String word) { int res = 0; for(int i=0;i<word.length();++i) { for(int j=i+4;j<word.length();++j) { if(isVowelString(word,i,j)) { res++; } } } return res; } }
[Leetcode]2063. 所有子字串中的母音
給你一個字串 word ,返回 word 的所有子字串中 母音的總數 ,母音是指 'a'、'e'、'i'、'o' 和 'u' 。
子字串 是字串中一個連續(非空)的字元序列。
注意:由於對 word 長度的限制比較寬鬆,答案可能超過有符號 32 位整數的範圍。計算時需當心。
遍歷 \(\textit{word}\), 若\(\textit{word}[i]\) 是母音,我們考察它能出現在多少個子字串中。
設 \(\textit{word}\) 的長度為 \(n\)。子字串 \(\textit{word}[l..r]\) 若要包含 \(\textit{word}[i]\)
\(0\le l\le i\)
\(i\le r\le n-1\)
這樣的 \(l\) 有 \(i+1\) 個,\(r\) 有 \(n-i\) 個,因此有 \((i+1)(n-i)\) 個子字串,所以 \(\textit{word}[i]\) 在所有子字串中一共出現了 \((i+1)(n-i)\) 次。
累加所有出現次數即為答案。
class Solution { public String Vowels = "aeiou"; public long countVowels(String word) { long res = 0; long n = word.length(); for(long i=0;i<n;++i) { Character ch = word.charAt((int)i); if(Vowels.indexOf(ch)!=-1) { res += (i+1) * (n-i); } } return res; } }
[Leetcode]2064. 分配給商店的最多商品的最小值
給你一個整數 n ,表示有 n 間零售商店。總共有 m 種產品,每種產品的數目用一個下標從 0 開始的整數陣列 quantities 表示,其中 quantities[i] 表示第 i 種商品的數目。
你需要將 所有商品 分配到零售商店,並遵守這些規則:
一間商店 至多 只能有 一種商品 ,但一間商店擁有的商品數目可以為 任意 件。
分配後,每間商店都會被分配一定數目的商品(可能為 0 件)。用 x 表示所有商店中分配商品數目的最大值,你希望 x 越小越好。也就是說,你想 最小化 分配給任意商店商品數目的 最大值 。
請你返回最小的可能的 x 。
二分法。
class Solution {
public int minimizedMaximum(int n, int[] quantities) {
int lo = 1,hi = Arrays.stream(quantities).max().getAsInt();
while(lo<=hi) {
int mid = lo+((hi-lo)>>1);
if(canDistribute(n,quantities,mid)) hi = mid -1;
else lo = mid+1;
}
return lo;
}
public boolean canDistribute(int n, int[] quantities, int target) {
int times = 0;
for(int quantity:quantities) {
times += quantity/target;
if(quantity%target!=0) times++;
}
if(times>n) return false;
return true;
}
}
[Leetcode]2065. 最大化一張圖中的路徑價值
給你一張 無向 圖,圖中有 n 個節點,節點編號從 0 到 n - 1 (都包括)。同時給你一個下標從 0 開始的整數陣列 values ,其中 values[i] 是第 i 個節點的 價值 。同時給你一個下標從 0 開始的二維整數陣列 edges ,其中 edges[j] = [uj, vj, timej] 表示節點 uj 和 vj 之間有一條需要 timej 秒才能通過的無向邊。最後,給你一個整數 maxTime 。
合法路徑 指的是圖中任意一條從節點 0 開始,最終回到節點 0 ,且花費的總時間 不超過 maxTime 秒的一條路徑。你可以訪問一個節點任意次。一條合法路徑的 價值 定義為路徑中 不同節點 的價值 之和 (每個節點的價值 至多 算入價值總和中一次)。
請你返回一條合法路徑的 最大 價值。
注意:每個節點 至多 有 四條 邊與之相連。
DFS。根據題目的資料範圍,至多能走 \(10\) 條邊,這意味著搜尋的層數至多為 \(10\);同時,題目保證每個節點至多有四條邊與之相連,因此每次搜尋時至多會遞迴 \(4\) 次。因此計算量至多為 \(4^{10}\)。需要注意的就是經過一個節點,直接把其價值置空。
這樣,重複的經過就不會重複統計價格了。 當然DFS返回前需要還原現場。DFS的時候記錄的狀態包括路徑價值和,累計時間。
退出條件為:時間超過閾值。更新最大價值則必須在終點為0的時候才可。
class Solution {
public int res;
public int maximalPathQuality(int[] values, int[][] edges, int maxTime) {
res = values[0];
var graph = new HashMap<Integer,ArrayList<ArrayList<Integer>>>();
for(var edge:edges) {
int u=edge[0], v=edge[1],time=edge[2];
ArrayList<Integer> toConnection = new ArrayList<>() {{add(v);add(time);}};//Arrays.asList(v,time) ;
ArrayList<Integer> fromConnection = new ArrayList<>() {{add(u);add(time);}};
if(!graph.containsKey(u)) graph.put(u,new ArrayList<ArrayList<Integer>>());
if(!graph.containsKey(v)) graph.put(v,new ArrayList<ArrayList<Integer>>());
var toConnections = graph.getOrDefault(u,new ArrayList<ArrayList<Integer>>());
var fromConnections = graph.getOrDefault(v,new ArrayList<ArrayList<Integer>>());
toConnections.add(toConnection);
fromConnections.add(fromConnection);
}
dfs(0,0,0,values,maxTime,graph);
return res;
}
public void dfs(int curPoint, int curValue, int curTime, int[] values, int maxTime, HashMap<Integer,ArrayList<ArrayList<Integer>>> graph) {
curValue += values[curPoint];
values[curPoint] = 0;
if(curPoint==0) res = Math.max(res,curValue);
for(var toConnection:graph.getOrDefault(curPoint,new ArrayList<ArrayList<Integer>>())) {
int nextPoint = toConnection.get(0), useTime = toConnection.get(1);
if(curTime+useTime>maxTime) continue;
dfs(nextPoint,curValue,curTime+useTime,values.clone(),maxTime,graph);
}
}
}