[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;
}
}