Leetcode - 140双周赛

目录

一,3300. 替换为数位和以后的最小元素

二,3301. 高度互不相同的最大塔高和

三,3302. 字典序最小的合法序列

四,3303. 第一个几乎相等子字符串的下标


一,3300. 替换为数位和以后的最小元素

本题直接暴力求解,代码如下:

class Solution {
    public int minElement(int[] nums) {
        int mn = Integer.MAX_VALUE;
        for(int x : nums){
            int res = 0;
            while(x > 0){
                res += x%10;
                x /= 10;
            }
            mn = Math.min(mn, res);
        }
        return mn;
    }
}

二,3301. 高度互不相同的最大塔高和

本题求最大总高度,从贪心的角度想,那必然是每个塔的高度越大越好,所以可以将maximumHeight 数组从大到小排序,使用一个变量 p 记录当前所能取到的最大值,对于下一个数x来说:

  • 如果 x < p,就说明当前塔可以选取的高度为[1,x],一定选 x,这时将 p = x;
  • 如果 x >= p,由于数组从大到小排序的,所以当 x >= p 时,就说明 x 已经在之前取过了,此时塔可以选取的高度为[1,p-1](注:p是上一次取过的值,不能再取),一定选 p-1,此时将 p = p-1。
  • 注:题目要求所有塔的高度不能 <= 0,所以要加一个额外判断,如果 p <= 0,返回 -1

代码如下:

class Solution {
    public long maximumTotalSum(int[] h) {
        int n = h.length;
        long res = 0;
        Arrays.sort(h);
        int p = Integer.MAX_VALUE;
        for(int i=n-1; i>=0; i--){
            p = h[i] < p ? h[i] : p - 1; 
            if(p <= 0) return -1;
            res += p;
        }
        return res;
    }
}

三,3302. 字典序最小的合法序列

本题可以使用前后缀分解的方式来解决,可以预处理 suf[i]:对于 w1[i:] 的子序列来说,他能匹配w2的最长后缀为 w2[j:](j=suf[i]),然后直接枚举修改的下标:

  • 如果 w1[i] == w2[j],直接把 i 加入答案。因为题目要求字典序最小
  • 如果 w1[i] != w2[j],那么需要判断 suf[i+1] 是否小于等于 j+1,如果是,说明修改 w2[i] 后w2[j+1:] 是 w1[i+1:] 的子序列,此时一定要修改(只能修改一次),因为题目要求字典序最小,将 i 加入答案。

代码如下:

class Solution {
    public int[] validSequence(String word1, String word2) {
        char[] w1 = word1.toCharArray();
        char[] w2 = word2.toCharArray();
        int m = w1.length, n = w2.length;
        int[] suf = new int[m+1];//suf[i]:w2[j:]是w1[i:]的子序列(j=suf[i])
        suf[m] = n;
        for(int i=m-1, j=n-1; i>=0; i--){
            if(j>=0 && w1[i] == w2[j]){
                j--;
            }
            suf[i] = j + 1;
        }
        int[] ans = new int[n];
        int j = 0;
        boolean changed = false;
        for(int i=0; i<m; i++){
            if(w1[i] == w2[j] || !changed && suf[i+1]<=j+1){
                if(w1[i] != w2[j]){
                    changed = true;
                }
                ans[j++] = i;
                if(j == n) return ans;
            }
        }
        return new int[0];
    }
}

四,3303. 第一个几乎相等子字符串的下标

本题和T3类似,还是使用前后缀分解,只不过这里匹配的不是子序列而是子串,所以这里使用z函数来预处理前后缀,然后枚举修改的下标,判断它的前后缀加起来是否能组成 pattern。

代码如下:

class Solution {
    public int minStartingIndex(String s, String pattern) {
        int[] pre = zBox(pattern + s);
        int[] suf = zBox(rev(pattern) + rev(s));
        int m = s.length(), n = pattern.length();
        for(int i=n; i<=m; i++){
            if(pre[i] + suf[n+m-i] >= n-1)
                return i - n;
        }
        return -1;
    }
    int[] zBox(String s){
        char[] ch = s.toCharArray();
        int n = ch.length;
        int[] z = new int[n];
        z[0] = n;
        int l = 0, r = 0;
        for(int i=1; i<n; i++){
            z[i] = i < r ? Math.min(z[i-l], r-i) : 0;
            while(i + z[i] < n && ch[z[i]] == ch[i+z[i]]){
                l = i;
                r = i + z[i];
                z[i]++;
            }
        }
        return z;
    }
    String rev(String s){
        return new StringBuilder(s).reverse().toString();
    }
}
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶祇秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值