0
点赞
收藏
分享

微信扫一扫

单周赛 2022.1.30 题解汇总

T1 5993. 将找到的值乘以 2 

给你一个整数数组 nums ,另给你一个整数 original ,这是需要在 nums 中搜索的第一个数字。

接下来,你需要按下述步骤操作:

如果在 nums 中找到 original ,将 original 乘以 2 ,得到新 original(即,令 original = 2 * original)。
否则,停止这一过程。
只要能在数组中找到新 original ,就对新 original 继续 重复 这一过程。
返回 original 的 最终 值。

提示:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i], original <= 1000

解题思路:我们可以使用 HashSet 对数组里面的数进行存储,然后每次使用 HashSet 的 contains方法来进行判断,如果存在,original 乘 2 继续判断,如果不存在,直接返回 original。

代码和提交结果如下:

class Solution {
    public int findFinalValue(int[] nums, int original) {
        HashSet<Integer> set = new HashSet();
        for(int i = 0 ; i < nums.length ; i++){
            set.add(nums[i]);
        }
        while(set.contains(original)){
            original *= 2;
        }
        return original;
    }
}

 

T2 5981. 分组得分最高的所有下标 

给你一个下标从 0 开始的二进制数组 nums ,数组长度为 n 。nums 可以按下标 i( 0 <= i <= n )拆分成两个数组(可能为空):numsleft 和 numsright 。

numsleft 包含 nums 中从下标 0 到 i - 1 的所有元素(包括 0 和 i - 1 ),而 numsright 包含 nums 中从下标 i 到 n - 1 的所有元素(包括 i 和 n - 1 )。
如果 i == 0 ,numsleft 为 空 ,而 numsright 将包含 nums 中的所有元素。
如果 i == n ,numsleft 将包含 nums 中的所有元素,而 numsright 为 空 。
下标 i 的 分组得分 为 numsleft 中 0 的个数和 numsright 中 1 的个数之 和 。

返回 分组得分 最高 的 所有不同下标 。你可以按 任意顺序 返回答案。

 

 

提示:

  • n == nums.length
  • 1 <= n <= 105
  • nums[i] 为 0 或 1

解题思路:滑动窗口思想

我们可以使用一个 index 指针,使用它所指的位置来区分左右数组,当 index 等于 0 时,左数组为空,我们只需要统计 右数组值为 1 的元素个数。然后记为 count。

建立一个HashMap<Integer,List<Integer>>,key 为 count ,value 为 数组下标 index。

index 指针右移,如果 nums[index-1] == 0,说明左数组多了一个 0 ,右数组少了一个 0 (但是右数组不会因为少了一个 0 有变化)count++,如果 nums[index-1] == 1,说明左数组多了一个 1 (左数组多一个 1 count 不会有变化),右数组少了一个 1  , count--。

在遍历的过程中,更新HashMap的 key 和 value。

代码和提交结果如下:

class Solution {
    public static List<Integer> maxScoreIndices(int[] nums) {
        HashMap<Integer, List<Integer>> res = new HashMap<>();
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            if(nums[i] == 1){
                count++;
            }
        }
        ArrayList<Integer> list = new ArrayList<>();
        list.add(0);
        res.put(count,list);
        int max = count;
        for(int i = 1 ; i <= nums.length ;i++){
            if(nums[i-1] == 0){
                count++;
            }else{
                count--;
            }
            List<Integer> temp = res.getOrDefault(count, new ArrayList<Integer>());
            temp.add(i);
            res.put(count,temp);

            if(count > max){
                max = count;
            }
        }
        return res.get(max);
    }
}

T3 5994. 查找给定哈希值的子串 

给定整数 p 和 m ,一个长度为 k 且下标从 0 开始的字符串 s 的哈希值按照如下函数计算:

hash(s, p, m) = (val(s[0]) * p0 + val(s[1]) * p1 + ... + val(s[k-1]) * pk-1) mod m.
其中 val(s[i]) 表示 s[i] 在字母表中的下标,从 val('a') = 1 到 val('z') = 26 。

给你一个字符串 s 和整数 power,modulo,k 和 hashValue 。请你返回 s 中 第一个 长度为 k 的 子串 sub ,满足 hash(sub, power, modulo) == hashValue 。

测试数据保证一定 存在 至少一个这样的子串。

子串 定义为一个字符串中连续非空字符组成的序列。

 

提示:

  • 1 <= k <= s.length <= 2 * 104
  • 1 <= power, modulo <= 109
  • 0 <= hashValue < modulo
  • s 只包含小写英文字母。
  • 测试数据保证一定 存在 满足条件的子串。

解题思路:我们可以先把 p 的 k 次幂先存起来,用来解决大数幂的问题。然后滑动窗口求解即可。

代码和提交结果如下:

class Solution {
    public static String subStrHash(String s, int power, int modulo, int k, int hashValue) {
        long[] powNum = new long[k];
        power = power % modulo;
        for(int i = 0 ; i < k ; i++){
            if(i==0){
                powNum[i] = 1;
            }else{
                powNum[i] = (powNum[i-1] * power) % modulo;
            }
        }
        for(int l = 0 ; l + k <= s.length(); l++){
            int r = l + k ;
            String sub = s.substring(l,r);
            if(hash(sub,power,modulo,powNum) == hashValue){
                return sub;
            }
        }
        return "";
    }
    private static long hash(String s, int p, int m ,long[] powNum){
        long count = 0;
        for(int i = 0 ; i < s.length() ; i++){
            count += (s.charAt(i)-'a'+1)*powNum[i] % m;
            count %= m;
        }
        return  count % m;
    }
}

T4 没写出来

总结:难度确实可以。 

 

 

 

举报

相关推荐

0 条评论