連結:LeetCode
[Leetcode]2027. 轉換字元串的最少操作次數
給你一個字元串 s ,由 n 個字元組成,每個字元不是 'X' 就是 'O' 。
一次 操作 定義為從 s 中選出 三個連續字元 并将選中的每個字元都轉換為 'O' 。注意,如果字元已經是 'O' ,隻需要保持 不變 。
傳回将 s 中所有字元均轉換為 'O' 需要執行的 最少 操作次數。
周遊即可。
class Solution {
public int minimumMoves(String s) {
int i = 0, n = s.length();
int res = 0;
while(i<n) {
if(s.charAt(i) == 'X') {
res ++;
i += 3;
}
else {
i ++;
}
}
return res;
}
}
[Leetcode]2028. 找出缺失的觀測資料
現有一份 n + m 次投擲單個 六面 骰子的觀測資料,骰子的每個面從 1 到 6 編号。觀測資料中缺失了 n 份,你手上隻拿到剩餘 m 次投擲的資料。幸好你有之前計算過的這 n + m 次投擲資料的 平均值 。
給你一個長度為 m 的整數數組 rolls ,其中 rolls[i] 是第 i 次觀測的值。同時給你兩個整數 mean 和 n 。
傳回一個長度為 n 的數組,包含所有缺失的觀測資料,且滿足這 n + m 次投擲的 平均值 是 mean 。如果存在多組符合要求的答案,隻需要傳回其中任意一組即可。如果不存在答案,傳回一個空數組。
k 個數字的 平均值 為這些數字求和後再除以 k 。
注意 mean 是一個整數,是以 n + m 次投擲的總和需要被 n + m 整除。
mean * (m + n) 求總數。
sum(rolls) 求已經有的數量。
sum = mean * (m+n) - sum(rolls) 剩下需要補充的平均配置設定就行。< N * 1 或者 > N * 6 則不可能有合法配置設定。
class Solution {
public int[] missingRolls(int[] rolls, int mean, int n) {
int m = rolls.length, sum_ = 0;
for(var roll:rolls) {
sum_ += roll;
}
int rest = (m+n) * mean - sum_;
if(rest < n || rest > 6 * n) {
return new int[0];
}
int dev = rest / n;
int restNum = rest % n;
int[] res = new int[n];
Arrays.fill(res,dev);
for(int i=0;i<restNum;++i) {
res[i] += 1;
}
return res;
}
}
[Leetcode]2029. 石子遊戲 IX
Alice 和 Bob 再次設計了一款新的石子遊戲。現有一行 n 個石子,每個石子都有一個關聯的數字表示它的價值。給你一個整數數組 stones ,其中 stones[i] 是第 i 個石子的價值。
Alice 和 Bob 輪流進行自己的回合,Alice 先手。每一回合,玩家需要從 stones 中移除任一石子。
如果玩家移除石子後,導緻 所有已移除石子 的價值 總和 可以被 3 整除,那麼該玩家就 輸掉遊戲 。
如果不滿足上一條,且移除後沒有任何剩餘的石子,那麼 Bob 将會直接獲勝(即便是在 Alice 的回合)。
假設兩位玩家均采用 最佳 決策。如果 Alice 獲勝,傳回 true ;如果 Bob 獲勝,傳回 false 。
給你一個字元串 word ,如果 word 可以被放入 board 中,請你傳回 true ,否則請傳回 false 。
由于我們隻關心總和能否被 33 整除,我們可以将 \(\textit{stones}\) 按照模 3 的結果分為 3 組,即 0、1 和 2。
根據題意,第一回合不能移除 0,否則直接輸掉遊戲,是以第一回合隻能移除 1 或者 2。我們可以枚舉這兩種情況,如果其中一種可以讓 Alice 獲勝就傳回 \(\texttt{true}\),否則傳回 \(\texttt{false}\)
下面以第一回合移除 1 來說明。在不考慮移除 0 的前提下,後面的移除由于要滿足總和不能被 3 整除,是以移除的石子是固定的,整體構成一個 \(112121212\dots\) 循環的序列。
對于 0,由于移除之後不會改變總和模 33 的結果,是以不會改變後續 11 和 22 的移除順序,是以我們可以在序列的任意非開頭位置插入 0。兩人為了不讓自己輸掉,必然會按照上述序列進行,直到沒有石子,或某一方隻能移除導緻總和被 3 整除的石子時分出勝負。是以我們需要求出讓總和不能被 3 整除的最大的回合數,這相當于 \(112121212\dots\) 序列的最長長度,加上 0 的個數。
若該回合數為奇數,且還有剩餘石子,那麼下一回合要輪到 Bob 移除石子,且他隻能移除一枚讓總和被 3 整除的石子,于是 Alice 獲勝;否則 Bob 獲勝。
對于第一回合移除 2 的情況,同樣會構成一個 \(221212121\dots\) 循環的序列,做法同上。
class Solution {
public boolean stoneGameIX(int[] stones) {
HashMap<Integer,Integer> hm = new HashMap<>();
for(var stone:stones)
{
var key =stone % 3;
hm.put(key,hm.getOrDefault(key,0)+1);
}
hm.put(0,hm.getOrDefault(0,0)%2);
int n = 0;
for(var val:hm.values()) n += val;
boolean res = getRes(n,hm,1) || getRes(n,hm,2);
return res;
}
public boolean getRes(int n, HashMap hm, int first) {
var dic = (HashMap<Integer,Integer>)hm.clone();
if(dic.getOrDefault(first,0) == 0) {
return false;
}
dic.put(first,dic.get(first)-1);
var cur = first;
for(int i=0;i<n-1;++i) {
int need_to_remove;
if(dic.getOrDefault(0,0)>0) {
need_to_remove = 0;
}
else if(dic.getOrDefault(cur,0)>0) {
need_to_remove = cur;
}
else {
return (i & 1) == 0;
}
cur = (cur + need_to_remove) % 3;
dic.put(need_to_remove,dic.getOrDefault(need_to_remove,0)-1);
}
return false;
}
}
[Leetcode]2030. 含特定字母的最小子序列
給你一個字元串 s ,一個整數 k ,一個字母 letter 以及另一個整數 repetition 。
傳回 s 中長度為 k 且 字典序最小 的子序列,該子序列同時應滿足字母 letter 出現 至少 repetition 次。生成的測試用例滿足 letter 在 s 中出現 至少 repetition 次。
子序列 是由原字元串删除一些(或不删除)字元且不改變剩餘字元順序得到的剩餘字元串。
字元串 a 字典序比字元串 b 小的定義為:在 a 和 b 出現不同字元的第一個位置上,字元串 a 的字元在字母表中的順序早于字元串 b 的字元。
- 從原序列中删去n-k個元素,之後得到res
- res中有至少repetition 個letter
- res是滿足上面兩點要求的集合中字典序最小的。
class Solution {
public String smallestSubsequence(String s, int k, char letter, int repetition) {
int n = s.length();
int[] suffix_cnt = new int[n];
int acc = 0;
for(int i=n-1;i>=0;--i) {
if(s.charAt(i)==letter) acc ++;
suffix_cnt[i] = acc;
}
Deque <Character> stk = new LinkedList<>();
int x = 0;
for(int i=0;i<n;++i) {
int y = x;
while((stk.size()>0) && (stk.size()+(n-i-1)>=k) && (s.charAt(i) < stk.peek())) {
if(stk.peek() == letter) y--;
if(y+suffix_cnt[i]<repetition) break;
stk.pop();
x = y;
}
if(stk.size()<k) {
if(s.charAt(i) == letter || k - stk.size() > repetition - x) {
stk.push(s.charAt(i));
if (s.charAt(i) == letter) x++;
}
}
}
StringBuilder SB = new StringBuilder();
while (!stk.isEmpty())
{
SB.append(stk.pollLast());
}
return SB.toString();
}
}