zoukankan      html  css  js  c++  java
  • Leetcode 1423 可获得的最大点数

    题目定义:

    几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。
    每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。
    你的点数就是你拿到手中的所有卡牌的点数之和。
    给你一个整数数组 cardPoints 和整数 k,请你返回可以获得的最大点数。
    
    示例 1:
    输入:cardPoints = [1,2,3,4,5,6,1], k = 3
    输出:12
    解释:第一次行动,不管拿哪张牌,你的点数总是 1 。但是,先拿最右边的卡牌将会最大化你的可获得点数。
    最优策略是拿右边的三张牌,最终点数为 1 + 6 + 5 = 12。
    
    示例 2:
    输入:cardPoints = [2,2,2], k = 2
    输出:4
    解释:无论你拿起哪两张卡牌,可获得的点数总是 4 。
        
    示例 3:
    输入:cardPoints = [9,7,7,9,7,7,9], k = 7
    输出:55
    解释:你必须拿起所有卡牌,可以获得的点数为所有卡牌的点数之和。
        
    示例 4:
    输入:cardPoints = [1,1000,1], k = 1
    输出:1
    解释:你无法拿到中间那张卡牌,所以可以获得的最大点数为 1 。 
        
    示例 5:
    输入:cardPoints = [1,79,80,1,1,1,200,1], k = 3
    输出:202
    

    方式一(求出剩余卡牌点数之和):

        /*
        * 思路:
          * 记数组 cardPoints 的长度为 n,由于只能从开头和末尾拿 k 张卡牌,
          * 所以最后剩下的必然是连续的 n-k 张卡牌。
          * 我们可以通过求出剩余卡牌点数之和的最小值,来求出拿走卡牌点数之和的最大值。
        * 算法:
          * 剩余卡牌是连续的,使用一个固定长度为 n-k 的滑动窗口对数组 
          * cardPoints 进行遍历,求出滑动窗口最小值,然后用所有卡牌的点数之和减去该最小值,
          * 即得到了拿走卡牌点数之和的最大值。
        * */
    class Solution {
        public int maxScore(int[] cardPoints, int k) {
            int window = cardPoints.length - k;
            int sum = 0;
            for(int i = 0; i < window; i++)
                sum += cardPoints[i];
            int minSum = sum;
            for(int i = window; i < cardPoints.length; i++){
                sum += cardPoints[i] - cardPoints[i - window];
                minSum = Math.min(sum,minSum);
            }
            return Arrays.stream(cardPoints).sum() - minSum;
        }
    }
    
    

    方式二(将数组看成一个环,在环内查找最大和的子数组):

    class Solution {
        public int maxScore(int[] cardPoints, int k) {
            int ans = 0;
            int sum = 0;
            for(int i = 0; i < k; i++){
                sum += cardPoints[i];
            }
            int maxSum = sum;
            //因为只可以从最左边或最右边拿值,
            //所以查找最左边与最右边中连续K个数和最大值
            for(int i = 0; i < k; i++){
                sum += cardPoints[cardPoints.length - 1 - i];
                sum -= cardPoints[k - 1 - i] ;
                maxSum = Math.max(sum,maxSum);
            }
            return maxSum;
        }
    }
    

    参考:

    https://leetcode-cn.com/problems/maximum-points-you-can-obtain-from-cards/

  • 相关阅读:
    linux下拼接字符串的代码
    postgresql实现插入数据返回当前的主键ID
    记录一个linux下批处理的代码
    iptables
    mybatis获得执行insert的返回值
    git commit之后撤销
    仿照CIFAR-10数据集格式,制作自己的数据集
    C/C++ 在处理文件所在路径下创建子目录
    C/C++ 图像二进制存储与读取
    C/C++ 文件路径解析
  • 原文地址:https://www.cnblogs.com/CodingXu-jie/p/14380915.html
Copyright © 2011-2022 走看看