LeetCode第278场周赛题解

LeetCode第278场周赛题解,第1张

LeetCode第278场周赛题解

博客首页:崇尚学技术的科班人
小肖来了
今天给大家带来的文章是《LeetCode第278场周赛》
希望各位小伙伴们能够耐心的读完这篇文章
博主也在学习阶段,如若发现问题,请告知,非常感谢
同时也非常感谢各位小伙伴们的支持

文章目录

<1> 第一题

题目示例提示⭐思路⭐代码实现运行结果 <2> 第二题

题目示例提示⭐思路⭐代码实现运行结果 <3> 第三题

题目示例提示⭐思路⭐代码实现运行结果

<1> 第一题 题目

将找到的值乘以 2

给你一个整数数组 nums ,另给你一个整数 original ,这是需要在 nums 中搜索的第一>个数字。
接下来,你需要按下述步骤 *** 作:

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

返回 original的 最终 值。

示例

示例1:

输入:nums = [5,3,6,1,12], original = 3
输出:24
解释: 
- 3 能在 nums 中找到。3 * 2 = 6 。
- 6 能在 nums 中找到。6 * 2 = 12 。
- 12 能在 nums 中找到。12 * 2 = 24 。
- 24 不能在 nums 中找到。因此,返回 24 。

示例2:

输入:nums = [2,7,9], original = 4
输出:4
解释:
- 4 不能在 nums 中找到。因此,返回 4 。
提示

1 <= nums.length <= 10001 <= nums[i], original <= 1000 ⭐思路⭐

思路

这道题是签到题,我的做法是就是我们每一次进行数组遍历查找这个数是否在数组中,如果在的话,我们就将它进行倍增。如果不存在的话,就是最终结果了。记住每一个更新之后,我们都需要进行数组遍历,由于数组长度较小且最坏时间复杂度是O(n * n),所以时间复杂度是完全符合要求的。

代码实现
class Solution {
    
    public boolean check(int[] nums,int a){
        for(int i = 0; i < nums.length; i ++){
            if(nums[i] == a){
                return true;
            }
        }
        return false;
    }
    
    public int findFinalValue(int[] nums, int original) {
        
        while(true){
            boolean flag = true;
            flag = check(nums,original);
            if(flag == true){
                original = original * 2;
            }else{
                break;
            }
        }
        
        return original;
    }
}
运行结果

<2> 第二题 题目

分组得分最高的所有下标

给你一个下标从 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 的个数之 和 。
返回 分组得分 最高 的 所有不同下标 。你可以按 任意顺序 返回答案。

示例

示例1:

输入:nums = [0,0,1,0]
输出:[2,4]
解释:按下标分组
- 0 :numsleft 为 [] 。numsright 为 [0,0,1,0] 。得分为 0 + 1 = 1 。
- 1 :numsleft 为 [0] 。numsright 为 [0,1,0] 。得分为 1 + 1 = 2 。
- 2 :numsleft 为 [0,0] 。numsright 为 [1,0] 。得分为 2 + 1 = 3 。
- 3 :numsleft 为 [0,0,1] 。numsright 为 [0] 。得分为 2 + 0 = 2 。
- 4 :numsleft 为 [0,0,1,0] 。numsright 为 [] 。得分为 3 + 0 = 3 。
下标 2 和 4 都可以得到最高的分组得分 3 。
注意,答案 [4,2] 也被视为正确答案。

示例2:

输入:nums = [0,0,0]
输出:[3]
解释:按下标分组
- 0 :numsleft 为 [] 。numsright 为 [0,0,0] 。得分为 0 + 0 = 0 。
- 1 :numsleft 为 [0] 。numsright 为 [0,0] 。得分为 1 + 0 = 1 。
- 2 :numsleft 为 [0,0] 。numsright 为 [0] 。得分为 2 + 0 = 2 。
- 3 :numsleft 为 [0,0,0] 。numsright 为 [] 。得分为 3 + 0 = 3 。
只有下标 3 可以得到最高的分组得分 3 。

示例3:

输入:nums = [1,1]
输出:[0]
解释:按下标分组
- 0 :numsleft 为 [] 。numsright 为 [1,1] 。得分为 0 + 2 = 2 。
- 1 :numsleft 为 [1] 。numsright 为 [1] 。得分为 0 + 1 = 1 。
- 2 :numsleft 为 [1,1] 。numsright 为 [] 。得分为 0 + 0 = 0 。
只有下标 0 可以得到最高的分组得分 2 。
提示

n == nums.length1 <= n <= 105nums[i] 为 0 或 1 ⭐思路⭐

思路

这道题的话,如果是暴力求解的话;那么会可能超时。因为你要求一个总和以及求一个numleft数组中0的个数,所以如果暴力求解的话,时间复杂度是O(n * n)。这里我们使用前缀和数组以及先处理一个0的count数组,那么时间复杂度就是O(n)。然后就是枚举分界点了。

代码实现
class Solution {
       
    int N = 100010;
    int[] sum = new int[N];
    int[] count = new int[N];
    
    public List maxScoreIndices(int[] nums) {
        List list = new ArrayList<>();
        int max = 0;
        
        for(int i = 1; i <= nums.length; i ++){
            sum[i] = sum[i - 1] + nums[i - 1];
        }
        
        for(int i = 1; i <= nums.length; i ++){
            if(nums[i - 1] == 0){
                count[i] = count[i - 1] + 1;
            }else{
                count[i] = count[i - 1];
            }
        }
        
        for(int i = 0; i <= nums.length; i ++){
            int num = count[i] + sum[nums.length] - sum[i];
            if(num > max){
                list = new ArrayList<>();
                list.add(i);
                max = num;
            }else if(num == max){
                list.add(i);
            }
            //System.out.println(num);
        }
        
        return list;
    }
}
运行结果

<3> 第三题 题目

查找给定哈希值的子串

给定整数 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:

输入:s = "leetcode", power = 7, modulo = 20, k = 2, hashValue = 0
输出:"ee"
解释:"ee" 的哈希值为 hash("ee", 7, 20) = (5 * 1 + 5 * 7) mod 20 = 40 mod 20 = 0 。
"ee" 是长度为 2 的第一个哈希值为 0 的子串,所以我们返回 "ee" 。

示例2:

输入:s = "fbxzaad", power = 31, modulo = 100, k = 3, hashValue = 32
输出:"fbx"
解释:"fbx" 的哈希值为 hash("fbx", 31, 100) = (6 * 1 + 2 * 31 + 24 * 312) mod 100 = 23132 mod 100 = 32 。
"bxz" 的哈希值为 hash("bxz", 31, 100) = (2 * 1 + 24 * 31 + 26 * 312) mod 100 = 25732 mod 100 = 32 。
"fbx" 是长度为 3 的第一个哈希值为 32 的子串,所以我们返回 "fbx" 。
注意,"bxz" 的哈希值也为 32 ,但是它在字符串中比 "fbx" 更晚出现。
提示

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

思路

这道题的思路是看了一位大佬的做法,其实题目的意思很明了,但是就是做法上需要很精巧。其实该题是数据结构中a * x2 + b * x + c该算式怎样求的一个扩展版。如果我们前面会了的话,因为题目要求的是第一个位置,所以我们先从后往前进行计算,当往前移动的时候,无非就是减去最后一个字符的值,再加上进来的一个字符的值就是我们所要求的截取对应长度的值。

代码实现
class Solution {
    public String subStrHash(String s, int power, int modulo, int k, int hashValue) {
        int i = s.length() - k;
        long p = 1, h = 0;

        int ans = -1;
        for(int j = s.length() - 1; j >= i; j --){
            h = (h * power + s.charAt(j) - 'a' + 1) % modulo;
            p = p * power % modulo;
        }
        if(h == hashValue) ans = i;

        for(int j = i - 1; j >= 0; j --){
            h = (h * power + s.charAt(j) - 'a' + 1 - (s.charAt(j + k) - 'a' + 1) * p % modulo + modulo) % modulo;
            if(h == hashValue) ans = j;
        }
        return s.substring(ans,ans + k);
    }
}
运行结果

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5714578.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存