LeetCode第278场周赛题解
📒博客首页:崇尚学技术的科班人
小肖来了🏇
🍣今天给大家带来的文章是《LeetCode第278场周赛》🍣
🍣希望各位小伙伴们能够耐心的读完这篇文章🍣
🙏博主也在学习阶段,如若发现问题,请告知,非常感谢🙏
💗同时也非常感谢各位小伙伴们的支持💗
<1> 第一题
题目
给你一个整数数组
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<Integer> maxScoreIndices(int[] nums) {
List<Integer> 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);
}
}
运行结果
