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;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_43447128/article/details/113731581