[Leetcode Weekly Contest]264
連結:LeetCode
[Leetcode]2047. 句子中的有效單詞數
句子僅由小寫字母('a' 到 'z')、數字('0' 到 '9')、連字元('-')、標點符號('!'、'.' 和 ',')以及空格(' ')組成。每個句子可以根據空格分解成 一個或者多個 token ,這些 token 之間由一個或者多個空格 ' ' 分隔。
如果一個 token 同時滿足下述條件,則認為這個 token 是一個有效單詞:
僅由小寫字母、連字元和/或標點(不含數字)。
至多一個 連字元 '-' 。如果存在,連字元兩側應當都存在小寫字母("a-b" 是一個有效單詞,但 "-ab" 和 "ab-" 不是有效單詞)。
至多一個 標點符號。如果存在,標點符號應當位於 token 的 末尾 。
這裡給出幾個有效單詞的例子:"a-b."、"afad"、"ba-c"、"a!" 和 "!" 。
給你一個字串 sentence ,請你找出並返回 sentence 中 有效單詞的數目 。
遍歷即可。
class Solution { public int countValidWords(String sentence) { String[] words = sentence.split(" "); int res = 0; for(String word : words) { if(isValid(word)) { res+=1; } } return res; } public boolean isValid(String word) { if(word.isBlank()) return false; int dash = -1, n = word.length(); for(int idx=0; idx<n; idx++) { var ch = word.charAt(idx); if (ch == '-') { if(dash != -1) return false; else dash = idx; } else if(ch == '!' || ch == '.' || ch == ',') { if(idx != n-1) return false; } else if(Character.isDigit(ch)) return false; } if(dash!=-1 && (dash==0 || dash==n-1||!Character.isLowerCase(word.charAt(dash-1))||!Character.isLowerCase(word.charAt(dash+1)))) return false; return true; } }
[Leetcode]2048. 下一個更大的數值平衡數
如果整數 x 滿足:對於每個數位 d ,這個數位 恰好 在 x 中出現 d 次。那麼整數 x 就是一個 數值平衡數 。
給你一個整數 n ,請你返回 嚴格大於 n 的 最小數值平衡數 。
暴力即可。
class Solution { public int nextBeautifulNumber(int n) { while(true) { n++; if(isBeautifulNumber(n)) { return n; } } } public boolean isBeautifulNumber(int n) { String strN = String.valueOf(n); HashMap<Character,Integer> count = new HashMap<>(); for(var ch:strN.toCharArray()) { count.put(ch,count.getOrDefault(ch,0)+1); } for(var pair:count.entrySet()) { // int key = (int)(pair.getKey()) - (int)('0'); int key = Integer.parseInt(String.valueOf(pair.getKey())); if(key != pair.getValue()) return false; } return true; } }
[Leetcode]2049. 統計最高分的節點數目
給你一棵根節點為 0 的 二叉樹 ,它總共有 n 個節點,節點編號為 0 到 n - 1 。同時給你一個下標從 0 開始的整數陣列 parents 表示這棵樹,其中 parents[i] 是節點 i 的父節點。由於節點 0 是根,所以 parents[0] == -1 。
一個子樹的 大小 為這個子樹內節點的數目。每個節點都有一個與之關聯的 分數 。求出某個節點分數的方法是,將這個節點和與它相連的邊全部 刪除 ,剩餘部分是若干個 非空 子樹,這個節點的 分數 為所有這些子樹 大小的乘積 。
請你返回有 最高得分 節點的 數目 。
1.使用Map儲存當前節點,以及它的子節點。
2.利用DFS查詢並存儲當前節點下的節點個數。
3.遍歷計算各個節點刪除後的得分情況(0號節點沒有父節點)。
class Solution {
public int countHighestScoreNodes(int[] parents) {
Map<Integer, List<Integer>> map = new HashMap();
int[] count = new int[parents.length];
for(int i = 1; i < parents.length; i++){
List<Integer> list = new ArrayList(map.getOrDefault( parents[i], new ArrayList()));
list.add(i);
map.put(parents[i], list);
}
DFS(0, map, count);
long scoreMax = Integer.MIN_VALUE;
int nodes = 0;
for(int i = 0; i < parents.length; i++){
long score = 1;
if(parents[i] == -1){
List<Integer> list = new ArrayList( map.getOrDefault( i, new ArrayList() ) );
for(int num : list)
score *= count[num];
}else{
score = count[0] - count[i];
List<Integer> list = new ArrayList( map.getOrDefault( i, new ArrayList() ) );
for(int num : list)
score *= count[num];
}
if(scoreMax < score){
scoreMax = score;
nodes = 1;
}else if(score == scoreMax) ++nodes;
}
return nodes;
}
public void DFS(int index, Map<Integer, List<Integer>> map, int[] count){
List<Integer> list = new ArrayList( map.getOrDefault( index, new ArrayList() ) );
if(list.size() == 0){
count[index] = 1;
return;
}
for(int num : list){
DFS(num, map, count);
count[index] += count[num];
}
++count[index];
}
}
[Leetcode]2050. 並行課程 III
給你一個整數 n ,表示有 n 節課,課程編號從 1 到 n 。同時給你一個二維整數陣列 relations ,其中 relations[j] = [prevCoursej, nextCoursej] ,表示課程 prevCoursej 必須在課程 nextCoursej 之前 完成(先修課的關係)。同時給你一個下標從 0 開始的整數陣列 time ,其中 time[i] 表示完成第 (i+1) 門課程需要花費的 月份 數。
請你根據以下規則算出完成所有課程所需要的 最少 月份數:
如果一門課的所有先修課都已經完成,你可以在 任意 時間開始這門課程。
你可以 同時 上 任意門課程 。
請你返回完成所有課程所需要的 最少 月份數。
注意:測試資料保證一定可以完成所有課程(也就是先修課的關係構成一個有向無環圖)。
這是一道非常經典的拓撲排序的應用題目, 我們可以在拓撲排序的過程中,維護一個 dp[i] 陣列來表示當前到達節點 i 的最長時間即可。另外,我們也可用DFS的方法來做,維護一個最長時間即可。
class Solution {
public int minimumTime(int n, int[][] relations, int[] time) {
int[] inDegree = new int[n];
List<Integer>[] graph = new List[n];
for (int i = 0; i < n; i++) {
graph[i] = new ArrayList<>();
}
for (int[] edge : relations) {
int u = edge[0] - 1;
int v = edge[1] - 1;
graph[u].add(v);
inDegree[v]++;
}
int[] dist = new int[n];
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
queue.add(i);
dist[i] = time[i];
}
}
while (!queue.isEmpty()) {
int index = queue.poll();
for (int next : graph[index]) {
dist[next] = Math.max(dist[next], dist[index] + time[next]);
if (--inDegree[next] == 0) {
queue.add(next);
}
}
}
return Arrays.stream(dist).max().getAsInt();
}
}