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

Leetcode

posted @ 2022-06-01 20:59  Jamest  阅读(56)  评论(0编辑  收藏  举报