心算项目攻略:最大化卡牌得分技巧

news2024/12/22 20:37:05

目录

  • 题目
    • 描述
    • 代码
      • 逻辑原理
      • 总结
      • 解析:
      • 代码逻辑:
      • 示例场景:
      • 总结:

题目

选自力扣
心算项目的挑战比赛中,要求选手从 N 张卡牌中选出 cnt 张卡牌,若这 cnt 张卡牌数字总和为偶数,则选手成绩「有效」且得分为 cnt 张卡牌数字总和。 给定数组 cards 和 cnt,其中 cards[i] 表示第 i 张卡牌上的数字。 请帮参赛选手计算最大的有效得分。若不存在获取有效得分的卡牌方案,则返回 0。

描述

示例 1:

输入:cards = [1,2,8,9], cnt = 3

输出:18

解释:选择数字为 1、8、9 的这三张卡牌,此时可获得最大的有效得分 1+8+9=18。

示例 2:

输入:cards = [3,3,1], cnt = 1

输出:0

解释:不存在获取有效得分的卡牌方案。

提示:

1 < = c n t < = c a r d s . l e n g t h < = 1 0 5 1 <= cnt <= cards.length <= 10^5 1<=cnt<=cards.length<=105
1 < = c a r d s [ i ] < = 1000 1 <= cards[i] <= 1000 1<=cards[i]<=1000

这段代码是一个Java类Solution中的方法 maxmiumScore,其目的是从给定的整数数组cards中选择cnt个元素,使得这cnt个元素的和最大,同时这个和必须是偶数。如果找不到这样的组合,那么返回的是在给定约束下的最大可能的偶数和。

代码

下面是对代码的逐行分析:

class Solution {
    public int maxmiumScore(int[] cards, int cnt) {
        Arrays.sort(cards); // 对数组进行排序,便于后续处理
        int ans = 0; // 初始化答案为0
        int tmp = 0; // 用于累加当前考虑的cnt个最大数的和
        int odd = -1, even = -1; // 分别记录当前cnt个数中最大的奇数和偶数
        int end = cards.length - cnt; // 确定需要遍历的数组的结束位置

        // 遍历数组,从大到小选择cnt个数
        for (int i = cards.length - 1; i >= end; i--) {
            tmp += cards[i]; // 累加当前数
            if ((cards[i] & 1) != 0) { // 判断是否为奇数
                odd = cards[i]; // 更新最大的奇数
            } else {
                even = cards[i]; // 更新最大的偶数
            }
        }

        // 如果累加的和本身就是偶数,直接返回
        if ((tmp & 1) == 0) {
            return tmp;
        }

        // 尝试替换一个奇数为一个更大的偶数
        for (int i = cards.length - cnt - 1; i >= 0; i--) {
            if ((cards[i] & 1) != 0) { // 找到数组中更大的奇数
                if (even != -1) { // 如果当前组合中有偶数
                    ans = Math.max(ans, tmp - even + cards[i]); // 尝试替换,更新最大和
                    break; // 找到一个合适的替换后,跳出循环
                }
            }
        }

        // 尝试替换一个偶数为一个更大的奇数
        for (int i = cards.length - cnt - 1; i >= 0; i--) {
            if ((cards[i] & 1) == 0) { // 找到数组中更大的偶数
                if (odd != -1) { // 如果当前组合中有奇数
                    ans = Math.max(ans, tmp - odd + cards[i]); // 尝试替换,更新最大和
                    break; // 找到一个合适的替换后,跳出循环
                }
            }
        }

        return ans; // 返回最大偶数和
    }
}

Arrays.sort(cards); 这行代码是Java中使用标准库函数对数组进行排序的示例。这里,Arrays.sort() 方法被用来对一个名为 cards 的数组进行排序。

逻辑原理

Arrays.sort() 方法的实现依赖于具体的Java版本和数组元素的类型。对于基本类型如 int, double 等,它使用了一种名为“双轴快速排序”的算法。对于对象数组,它使用了“TimSort”,这是一种由归并排序和插入排序结合而成的算法,特别适用于部分有序的数组,效率很高。

总结

Arrays.sort(cards); 这行代码会根据 cards 数组元素的自然顺序或实现的 Comparable 接口进行排序。如果 cards 数组的元素是自定义对象,那么这些对象必须实现 Comparable 接口,或者你可以提供一个 Comparator 来自定义排序逻辑。否则,Arrays.sort() 将无法正确排序对象数组。


在Java中,tmp & 1是一个位运算表达式,这里使用的是按位与运算符&。这个表达式主要用于判断tmp这个整数是否为偶数还是奇数。

  • 按位与运算符&:它会将两个操作数的二进制形式进行按位逻辑与运算。对于每一位,如果两个位都是1,则结果位为1;否则结果位为0。

  • 与1进行按位与运算:当我们对一个整数x执行x & 1时,实际上只检查x的最低位(最右边的位)。这是因为1的二进制形式为00000001(对于32位整数),与任何数的最低位进行按位与运算时,结果将直接反映该位的值。

  • 判断奇偶性:由于任何整数的奇偶性都由其最低位决定(奇数的最低位为1,偶数的最低位为0),x & 1的值将直接告诉我们x是奇数还是偶数。如果x & 1的结果为1,那么x是奇数;如果结果为0,那么x是偶数。

例如:

  • 如果tmp = 4,它的二进制表示为00000100,那么tmp & 1 = 0,因为00000100 & 00000001 = 00000000,所以tmp是偶数。
  • 如果tmp = 5,它的二进制表示为00000101,那么tmp & 1 = 1,因为00000101 & 00000001 = 00000001,所以tmp是奇数。

在代码中,tmp & 1用于判断tmp的和是否为偶数,从而决定是否需要进行替换操作以确保最终结果为偶数。


这行代码是算法中常见的一类更新最大值(或最小值)的操作,通常出现在动态规划、滑动窗口、贪心算法等解决最优化问题的场景中。我们来详细解析一下这行代码:

ans = Math.max(ans, tmp - even + cards[i]);

解析:

  1. ans:这通常表示当前已知的最优解。在算法执行过程中,ans 会不断更新,最终存储的是问题的最优解。

  2. Math.max():这是Java中的一个方法,用于返回两个参数中的最大值。这里它被用来比较当前的 ans 和一个新的计算值,如果新的计算值更大,就用它来更新 ans

  3. tmp:这可能是之前计算的一个中间值,它在算法中可能代表了某种累积效果或状态。

  4. even:这通常是一个常量或变量,可能代表某种固定的值,例如在特定问题中,even 可能是所有偶数元素的和,或者是某种需要从 tmp 中减去的值。

  5. cards[i]:这是一个数组 cards 中的第 i 个元素。在算法中,cards 可能代表一系列需要处理的输入数据。

代码逻辑:

这行代码的核心逻辑是在更新 ans,它比较了当前的 anstmp - even + cards[i] 的值,如果后者更大,那么 ans 就会被更新。这通常发生在需要在一系列操作或状态转换中找到最大值的场景,例如在动态规划问题中,我们经常需要根据之前的状态来计算当前状态的值,并在所有可能的状态中选择最大的那个作为最终状态。

示例场景:

假设我们在求解一个数组中的最大子数组和问题,其中 tmp 表示到当前位置为止的连续子数组和,even 是一个与问题无关的示例值(这里仅为了说明而加入,实际情况可能不同),cards[i] 表示当前元素。每次迭代时,我们通过 tmp - even + cards[i] 来计算更新后的子数组和,并与当前记录的最大值 ans 比较,如果新值更大,就更新 ans

总结:

这行代码是算法设计中更新最优解的常见模式,它体现了算法设计中比较和选择最优解的核心思想。


public class Solution {
public int maximumScore(int[] cards, int cnt) {
int[] frequency = new int[1001]; // 直接初始化数组

    // 计算每种数字出现的频率
    for (int card : cards) {
        frequency[card]++;
    }

    int score = 0;
    int remainingCount = cnt;
    int highestOdd = -1;
    int highestEven = -1;
    int lastTakenValue = -1;

    // 从大到小选择卡牌
    for (int i = 1000; i >= 1 && remainingCount > 0; i--) {
        if (frequency[i] > 0) {
            int takeCount = Math.min(frequency[i], remainingCount); // 取能取的最大数量
            score += takeCount * i; // 更新得分
            remainingCount -= takeCount; // 更新剩余需要选择的数量

            // 更新最高的奇数和偶数
            if (i % 2 == 0) {
                highestEven = i;
            } else {
                highestOdd = i;
            }

            // 更新上一次取的数字
            lastTakenValue = i;
        }
    }

    // 如果得分已经是偶数,则直接返回
    if (score % 2 == 0) {
        return score;
    }

    // 尝试替换一张卡牌以使总和变为偶数
    for (int i = lastTakenValue - 1; i >= 1 && remainingCount > 0; i--) {
        if (frequency[i] > 0) {
            if (highestOdd != -1 && i % 2 == 0) { // 替换偶数卡片
                return Math.max(score, score - highestEven + i);
            } else if (highestEven != -1 && i % 2 != 0) { // 替换奇数卡片
                return Math.max(score, score - highestOdd + i);
            }
        }
    }

    // 如果无法找到合适的替换方案,则返回 0
    return 0;
}

}
测试
public class Driver {
public static void main(String[] args) {
int[] param_1 = {1, 2, 3, 4, 5}; // 示例数组
int param_2 = 3; // 示例计数
Solution solution = new Solution();
int ret = solution.maximumScore(param_1, param_2);
System.out.println("Maximum Score: " + ret);
}
}在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1970773.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI绘画工具推荐:Stable Diffusion的新境界

前言 在AI绘画的世界里&#xff0c;Stable Diffusion无疑是一颗璀璨的明星。然而&#xff0c;对于许多用户来说&#xff0c;切换不同的UI界面和管理众多模型是一项挑战。今天&#xff0c;我们为大家介绍一款革命性的工具——Stability Matrix&#xff0c;它将彻底改变你对Stabl…

JavaScript前端面试题——fetch

什么是fetch&#xff1f; fetch&#xff1a;fetch是浏览器内置的api&#xff0c;用于发送网络请求 ajax&axios&fetch的关系 ajax&#xff1a;ajax 是一种基于原生 JavaScript 的异步请求技术。它使用 XMLHttpRequest 对象来发送请求和接收响应。 axios&#xff1a;…

MP4标准格式深度解析

&#x1f60e; 作者介绍&#xff1a;欢迎来到我的主页&#x1f448;&#xff0c;我是程序员行者孙&#xff0c;一个热爱分享技术的制能工人。计算机本硕&#xff0c;人工制能研究生。公众号&#xff1a;AI Sun&#xff08;领取大厂面经等资料&#xff09;&#xff0c;欢迎加我的…

校园选课助手【1】-项目整体架构从此开始

项目背景 随着高校招生规模的不断扩大&#xff0c;学生选课需求日益增长。为提高选课效率&#xff0c;降低学生选课压力&#xff0c;本项目旨在开发一款校园选课助手软件。 项目目标:开发一款具有以下特点的校园选课助手软件&#xff1a; 易用性&#xff1a;界面简洁&#xff…

微信-公众号/订阅号推送消息(js版本)

1.登录或注册微信测试号 &#xff08;测试号的名称由官方自动生成&#xff0c;不能更改&#xff09; 微信测试号入口&#xff1a;微信公众平台 ​ 2.登录进去后会看到自己的appId和appsecret &#xff08;这两个参数都需填入代码中&#xff09; ​ 3.检查是否安装nodeJs…

《刚刚问世》系列初窥篇-Java+Playwright自动化测试-3-启动浏览器(详细教程)

软件测试微信群&#xff1a;https://bbs.csdn.net/topics/618423372 有兴趣的可以扫码加入 1.简介 通过前边两篇文章跟随宏哥学习想必到这里已经将环境搭建好了&#xff0c;今天就在Java项目搭建环境中简单地实践一下&#xff1a; 启动两大浏览器。按市场份额来说&#xff0c…

[极客大挑战 2019]BuyFlag1

这个题目比较常规&#xff0c;算是我遇到的简单题&#xff0c;也是这段时间第一个独立解出的&#xff0c;有点小开心。 首先打开靶机&#xff0c;一个平平无奇的纳新页面&#xff0c;很容易找到 /pay.php 看一下pay.php 这里说了几个条件&#xff1a;需要100000000&#xff0c…

【iOS】copystrong原理+深浅拷贝+完全拷贝

Copy&Strong原理 Copy探究 在回答copy的各种问题前&#xff0c;我们需要先了解我们为什么要使用copy。 拷贝的目的 &#xff1a; 产生一个副本对象&#xff0c;跟源对象互不影响 修改了源对象&#xff0c;不会影响副本对象修改了副本对象&#xff0c;不会影响源对象 iOS…

量化方法怎么选?如何评估量化后的大模型LLM?

文章内容总结自&#xff1a;Evaluating Quantized Large Language Models&#xff08;https://arxiv.org/abs/2402.18158&#xff09; 如果想深入了解量化的基本概念和如何用代码实现请参考&#xff1a; Michael&#xff1a;用python代码深入浅出量化概念 &#xff08;https…

YOLOv10改进 | 注意力篇 | YOLOv10引入SpatialGroupEnhance注意力机制,并构建C2f_SGE

1. SGE介绍 1.1 摘要:卷积神经网络(CNN)通过收集语义子特征的层次和不同部分来生成复杂对象的特征表示。这些子特征通常可以以分组的形式分布在每层的特征向量中[43,32],代表各种语义实体。然而,这些子特征的激活通常在空间上受到相似模式和噪声背景的影响,从而导致错误…

虚拟机win server安装配置DNS服务器

准备工作 创建DNS服务器前将自己的网卡地址设置为静态IP&#xff0c;选择自己的网卡。因为本机作为DNS服务器所以将DNS服务器地址设为了自己的回环地址。 一、使用服务器管理安装 DNS 服务器 1、登录服务器后&#xff0c;服务器会默认启用“服务器管理”页面&#xff0c;选择…

提前批测开三面,已OC!

大家好&#xff0c;我是洋子 近期百度提前批已经开始有一段时间了&#xff0c;甚至已经有不少 25 届的同学 oc 了&#xff0c;这里分享一位已经顺利 oc 百度提前批测开岗位同学的三轮面试面经 整个三轮技术面试总体难度不高&#xff0c;但考察知识广度比较广&#xff0c;如果…

搭建 STM32 网关服务器的全流程:集成嵌入式 C++、TCP/IP 通信、Flash 存储及 JWT 认证(含代码示例)

引言 随着物联网&#xff08;IoT&#xff09;技术的快速发展&#xff0c;基于 STM32 的服务器&#xff08;类似网关&#xff09;在数据采集、设备控制等方面的应用越来越广泛。本文将介绍搭建一个基于 STM32 的服务器所需的技术栈&#xff0c;以及详细的搭建步骤和代码示例。 …

好的养宠空气净化器是智商税吗?好的养宠空气净化器用户体验

家里养了两只“超级掉毛怪”,家里的猫毛满天飞&#xff0c;衣服床餐具等到处都是&#xff01;感受一下40度高温的养猫人&#xff0c;给掉毛怪疏毛浮毛飘飘&#xff0c;逃不过的饮水机&#xff0c;各个角落&#xff0c;多猫拉臭传来的异味。 一、养猫需要解决的问题 掉毛&#…

Tsan-ThreadSanitizer之As if synchronized via sleep

最近在调试ffmpeg的时候&#xff0c;加入了tsan&#xff0c;结果出现了下面提示&#xff1a; 具体什么意思呢&#xff0c;找了很久找到了官方介绍&#xff1a; https://github.com/google/sanitizers/wiki/ThreadSanitizerReportFormat

大数据-61 Kafka 高级特性 消息消费02-主题与分区 自定义反序列化 拦截器 位移提交 位移管理 重平衡

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Git的一些简单使用

下列内容适用于git初学者&#xff0c;从创建本地git仓库到提交的一个基本过程1. 1.创建git仓库 在想创建git仓库的路径下打开git bash&#xff0c;输入以下命令行创建仓库&#xff08;一般来说&#xff0c;我觉得直接在code workspace得地方创建git仓库就可以了&#xff0c;这…

acme.sh生成https证书

前言 SSL 价格并不便宜, 本节介绍如何使用 acme.sh 生成免费的 SSL 证书 证书生成原理 CA && Let’s Encrypt 证书颁发机构&#xff08;CA&#xff0c;Certificate Authority&#xff09;是一个负责颁发数字证书的实体。数字证书用于在互联网上验证实体的身份&…

注册或购买的谷歌账号的辅助邮箱是否需要设置?有什么用?设置的要点是什么?

今天早上&#xff0c;有个朋友联系到GG账号服务&#xff0c;问我谷歌账号辅助邮箱怎么用。说实在的这个问题有点抽象&#xff0c;哈哈。 然后我详细了解了一下&#xff0c;原来是这样的&#xff1a; 他的谷歌账号提示异常&#xff08;这个时候账号肯定是被停用了的&#xff09…

【Linux应用编程】Day12线程

线程 与进程类似&#xff0c;线程是允许应用程序并发执行多个任务的一种机制&#xff0c;线程参与系统调度&#xff1b; 事实上&#xff0c;系统调度的最小单元是线程、而并非进程。 ⚫ 线程的基本概念&#xff0c;线程 VS 进程&#xff1b; ⚫ 线程标识&#xff1b; ⚫ 线…