Leetcode刷题 2021.02.06
Leetcode1423 可获得的最大点数
几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。
每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。
你的点数就是你拿到手中的所有卡牌的点数之和。
给你一个整数数组 cardPoints 和整数 k,请你返回可以获得的最大点数。
其实如果不是滑窗月的话要考虑一下的,一开始想到dp去了。后来想一想,能去的牌只能是最前面和最后面的元素的组合,那就很简单了。滑动窗口遍历每一种可能取最大值就行了。
class Solution {
public int maxScore(int[] cardPoints, int k) {
int n = cardPoints.length, sum = 0, res = 0;
//前k种可能
for(int i = 0; i < k; i++){
sum += cardPoints[i];
}
res = Math.max(res, sum);
//前面减去一个,后面加一个,直到后面元素为k个
for(int i = 0; i < k; i++){
sum -= cardPoints[k - i - 1];
sum += cardPoints[n - 1 - i];
res = Math.max(res, sum);
}
return res;
}
}
Leetcode1695 删除子数组的最大得分
给你一个正整数数组 nums ,请你从中删除一个含有 若干不同元素 的子数组。删除子数组的 得分 就是子数组各元素之 和 。
返回 只删除一个 子数组可获得的 最大得分 。
如果数组 b 是数组 a 的一个连续子序列,即如果它等于 a[l],a[l+1],…,a[r] ,那么它就是 a 的一个子数组。
也是比较容易想到的滑窗题,因为要求子数组,且要求不同元素,那么窗口里的元素必须是唯一的。遍历记录最大值即可,可以用set或者数组记录是否已经出现过该元素。
class Solution {
public int maximumUniqueSubarray(int[] nums) {
int n = nums.length, i = 0, j = 0, res = 0, sum = 0;
// Set<Integer> set = new HashSet<>();
//用set或者数组记录,数组就能击败100%了
int[] map = new int[10001];
while (j < n){
//先加入该元素
sum += nums[j];
//如果窗口里出现过的话
if (map[nums[j]] == 1){
int temp = nums[j];
//缩小窗口,直到减去该元素,map里也要相应删掉
while (nums[i] != temp){
sum -= nums[i];
map[nums[i]] = 0;
i++;
}
//目标值还没减,再减一次
sum -= nums[i];
map[nums[i]] = 0;
i++;
}
//map加入该元素,记录最大值即可
map[nums[j]] = 1;
j++;
res = Math.max(res, sum);
}
return res;
}
}
Leetcode1630 等差子数组
如果一个数列由至少两个元素组成,且每两个连续元素之间的差值都相同,那么这个序列就是 等差数列 。更正式地,数列 s 是等差数列,只需要满足:对于每个有效的 i , s[i+1] - s[i] == s1 - s[0] 都成立。
这题没什么好的想法,看了看数据规模,都不是很大,所以想只能暴力解了。看了题解也都是暴力做的,没什么好讲的了。
class Solution {
public List<Boolean> checkArithmeticSubarrays(int[] nums, int[] l, int[] r) {
List<Boolean> res = new ArrayList<>();
int m = l.length;
for(int i = 0; i < m; i++){
//获取每一个子数组
int[] temp = new int[r[i] - l[i] + 1];
for(int j = 0; j < temp.length; j++){
temp[j] = nums[j + l[i]];
}
//先排序,再判断该数组是否是等差数组
Arrays.sort(temp);
res.add(helper(temp));
}
return res;
}
//判断有序数组是否是等差数组
private boolean helper(int[] temp){
int n = temp.length;
if (n <= 2) return true;
int diff = temp[1] - temp[0];
for(int i = 1; i < n; i++){
if (temp[i] - temp[i - 1] != diff) return false;
}
return true;
}
}