博客首页:崇尚学技术的科班人
小肖来了
今天给大家带来的文章是《LeetCode第278场周赛》
希望各位小伙伴们能够耐心的读完这篇文章
博主也在学习阶段,如若发现问题,请告知,非常感谢
同时也非常感谢各位小伙伴们的支持
将找到的值乘以 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 <= 1000
1 <= 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;
}
}
分组得分最高的所有下标
给你一个下标从
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.length
1 <= n <= 105
nums[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;
}
}
查找给定哈希值的子串
给定整数
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 * 104
1 <= power, modulo <= 109
0 <= hashValue < modulo
s
只包含小写英文字母思路
这道题的思路是看了一位大佬的做法,其实题目的意思很明了,但是就是做法上需要很精巧。其实该题是数据结构中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);
}
}