[Leetcode Weekly Contest]291
連結:LeetCode
[Leetcode]2259. 移除指定數字得到的最大結果
給你一個表示某個正整數的字串 number 和一個字元 digit 。
從 number 中 恰好 移除 一個 等於 digit 的字元後,找出並返回按 十進位制 表示 最大 的結果字串。生成的測試用例滿足 digit 在 number 中出現至少一次。
按照以下策略移除數字可以使得最終結果最大:
- 我們從左至右遍歷 \(\textit{number}\),如果遍歷到 \(\textit{number}[i] = \textit{digit}\),且 \(\textit{number}[i] < \textit{number}[i + 1]\)
- 如果遍歷完成依舊不存在滿足上一個條件的下標,則我們刪除 \(\textit{digit}\) 出現的最後一個下標,此時刪除該字元後得到的結果最大。
class Solution { public String removeDigit(String number, char digit) { int index = -1; String res = null; for(int i=0;i<number.length();++i) { if(i!=number.length()-1 && number.charAt(i) == digit && number.charAt(i+1)>number.charAt(i)) { res = number.substring(0, i) + number.substring(i+1, number.length()); break; } if(number.charAt(i) == digit) index=i; } if(res!=null) return res; res = number.substring(0, index) + number.substring(index+1, number.length()); return res; } }
[Leetcode]2260. 必須拿起的最小連續卡牌數
給你一個整數陣列 cards ,其中 cards[i] 表示第 i 張卡牌的 值 。如果兩張卡牌的值相同,則認為這一對卡牌 匹配 。
返回你必須拿起的最小連續卡牌數,以使在拿起的卡牌中有一對匹配的卡牌。如果無法得到一對匹配的卡牌,返回 -1 。
雜湊表,記錄每個card的索引即可。
class Solution { public int minimumCardPickup(int[] cards) { int res = Integer.MAX_VALUE; HashMap<Integer, Integer> cardIndex = new HashMap<>(); for(int i=0;i<cards.length;++i) { int card = cards[i]; if(cardIndex.containsKey(card)) { res = Math.min(res, i-cardIndex.get(card)+1); cardIndex.put(card, i); } else { cardIndex.put(card, i); } } return res==Integer.MAX_VALUE? -1 : res; } }
[Leetcode]2261. 含最多 K 個可整除元素的子陣列
給你一個整數陣列 nums 和兩個整數 k 和 p ,找出並返回滿足要求的不同的子陣列數,要求子陣列中最多 k 個可被 p 整除的元素。
如果滿足下述條件之一,則認為陣列 nums1 和 nums2 是 不同 陣列:
- 兩陣列長度 不同 ,或者
- 存在 至少 一個下標 i 滿足 nums1[i] != nums2[i] 。
子陣列 定義為:陣列中的連續元素組成的一個 非空 序列。
滑動視窗。移動end指標,作為子陣列右端點,同時收縮左指標,保證滑窗內是符合要求的子陣列,即最多k個可以被p整除的元素。
class Solution {
public int countDistinct(int[] nums, int k, int p) {
int start = 0;
HashSet<Integer> set = new HashSet<>();
HashSet<String> res = new HashSet<>();
int count = 0;
for(int end=0;end<nums.length;++end) {
if(nums[end] % p == 0) {
count ++;
set.add(end);
}
if(count > k) {
while(!set.contains(start)) start ++;
start ++;
count --;
}
addArray(res, nums, start, end);
}
return res.size();
}
public void addArray(HashSet<String> res, int[] nums, int start, int end) {
String value = "";
for(int ind=end;ind>=start;ind--) {
value += ("-" + nums[ind]);
res.add(value);
}
}
}
[Leetcode]2262. 字串的總引力
字串的 引力 定義為:字串中 不同 字元的數量。
例如,"abbca" 的引力為 3 ,因為其中有 3 個不同字元 'a'、'b' 和 'c' 。
給你一個字串 s ,返回 其所有子字串的總引力 。
子字串 定義為:字串中的一個連續字元序列。
找規律,分類討論:
如果 \(s[i]\) 之前沒有遇到過,那麼這些子串的引力值都會增加 1,這些子串的引力值之和會增加 i,再加上 1,即 \(s[i]\) 單獨組成的子串的引力值;
如果 \(s[i]\) 之前遇到過,設其上次出現的下標為 j,那麼向子串 \(s[0..i-1],\ s[1..i-1],\ s[2..i-1],\cdots,s[j..i-1]\) 的末尾新增 \(s[i]\) 後,這些子串的引力值是不會變化的,因為 \(s[i]\) 已經在 \(s[j]\) 處出現過了;而子串 \(s[j+1..i-1],\ s[j+2..i-1],\cdots,s[i-1..i-1]\) 由於不包含字元 \(s[i]\),這些子串的引力值都會增加 1,因此有 \(i-j-1\) 個子串的引力值會增加 1,這些子串的引力值之和會增加 \(i-j-1\),再加上 1,即 \(s[i]\) 單獨組成的子串的引力值。
class Solution {
public long appealSum(String s) {
long cur = 0, res = 0;
HashMap<Character, Integer> hash = new HashMap<>();
for(int i=0;i<s.length();++i) {
char ch = s.charAt(i);
if(!hash.containsKey(ch)) {
cur += i+1;
}
else {
cur += i-hash.get(ch);
}
res += cur;
hash.put(ch, i);
}
return res;
}
}