LeetCode 2897. 对数组执行操作使平方和最大【贪心,位运算,哈希表】2301

本文主要是介绍LeetCode 2897. 对数组执行操作使平方和最大【贪心,位运算,哈希表】2301,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你一个下标从 0 开始的整数数组 nums 和一个  整数 k 。

你可以对数组执行以下操作 任意次 :

  • 选择两个互不相同的下标 i 和 j ,同时 将 nums[i] 更新为 (nums[i] AND nums[j]) 且将 nums[j] 更新为 (nums[i] OR nums[j]) ,OR 表示按位  运算,AND 表示按位  运算。

你需要从最终的数组里选择 k 个元素,并计算它们的 平方 之和。

请你返回你可以得到的 最大 平方和。

由于答案可能会很大,将答案对 10^9 + 7 取余 后返回。

示例 1:

输入:nums = [2,6,5,8], k = 2
输出:261
解释:我们可以对数组执行以下操作:
- 选择 i = 0 和 j = 3 ,同时将 nums[0] 变为 (2 AND 8) = 0 且 nums[3] 变为 (2 OR 8) = 10 ,结果数组为 nums = [0,6,5,10]- 选择 i = 2 和 j = 3 ,同时将 nums[2] 变为 (5 AND 10) = 0 且 nums[3] 变为 (5 OR 10) = 15 ,结果数组为 nums = [0,6,0,15] 。
从最终数组里选择元素 156 ,平方和为 152 + 62 = 261261 是可以得到的最大结果。

示例 2:

输入:nums = [4,5,4,7], k = 3
输出:90
解释:不需要执行任何操作。
选择元素 754 ,平方和为 72 + 52 + 42 = 9090 是可以得到的最大结果。

提示:

  • 1 <= k <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^9

解法 位运算+贪心+哈希表

一个直接的感受是,如果将一个数和其他更多的数按位与,则结果会越来越小;如果将一个数和其他更多的数按位或,则结果会越来越大。

现在对 n u m s [ i ] nums[i] nums[i] n u m s [ j ] nums[j] nums[j] 同时更新,对于同一个比特位,由于 AND 和 OR 不会改变都为 0 0 0 和都为 1 1 1 的情况,所以操作等价于:把一个数的 0 0 0 和另一个数的同一个比特位上的 1 1 1 交换

假设交换前两个数是 x , y x,y x,y ,且 x > y x > y x>y 。则把小的数上的 1 1 1 给大的数,假设交换后 x x x 增加了 d d d ,则 y y y 也减少了 d d d

  • 交换前: x 2 + y 2 x^2 + y^2 x2+y2
  • 交换后: ( x + d ) 2 + ( y − d ) 2 = x 2 + y 2 + 2 d ( x − y ) + 2 d 2 > x 2 + y 2 (x+d)^2 + (y - d)^2 = x^2 + y^2 + 2d(x - y) + 2d^2 > x^2 +y^2 (x+d)2+(yd)2=x2+y2+2d(xy)+2d2>x2+y2

这说明应该通过交换,让一个数越大越好。相当于 1 1 1聚集在一个数中,比分散到不同数中更好

由于可以操作任意次,那么一定可以「组装」出尽量大的数:做法如下:

  1. 对每个比特位,统计 n u m s nums nums 数组中的元素在这个比特位上有多少个 1 1 1 ,记到一个长至多为 30 30 30 c n t cnt cnt 数组中(因为 1 0 9 < 2 30 10^9 < 2^{30} 109<230
  2. 循环 k k k 次。每次循环,组装一个数(记为 x x x):遍历 c n t cnt cnt ,只要 c n t [ i ] > 0 cnt[i] > 0 cnt[i]>0 就将其减一,同时将 2 i 2^i 2i 加到 x x x 中。这样相当于把 1 1 1 尽量聚集在一个数中。
  3. x 2 x^2 x2 加到答案中。
class Solution {
public:int maxSum(vector<int>& nums, int k) {int cnt[31] {};for (int num : nums)for (int i = 0; i < 31; ++i)cnt[i] += ((num >> i) & 1);long long ans = 0;const int MOD = 1e9 + 7;while (k--) {int x = 0;for (int i = 0; i < 31; ++i) {if (cnt[i]) {x |= 1 << i;cnt[i]--;}}ans = (ans + (long long)x * x) % MOD;}return ans;}
};

复杂度分析:

  • 时间复杂度: O ( n log ⁡ U ) \mathcal{O}(n\log U) O(nlogU) ,其中 n n n nums \textit{nums} nums 的长度, U = max ⁡ ( nums ) U=\max(\textit{nums}) U=max(nums)
  • 空间复杂度: O ( log ⁡ U ) \mathcal{O}(\log U) O(logU)

这篇关于LeetCode 2897. 对数组执行操作使平方和最大【贪心,位运算,哈希表】2301的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/237079

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

解密SQL查询语句执行的过程

《解密SQL查询语句执行的过程》文章讲解了SQL语句的执行流程,涵盖解析、优化、执行三个核心阶段,并介绍执行计划查看方法EXPLAIN,同时提出性能优化技巧如合理使用索引、避免SELECT*、JOIN... 目录1. SQL语句的基本结构2. SQL语句的执行过程3. SQL语句的执行计划4. 常见的性能优

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

如何在Java Spring实现异步执行(详细篇)

《如何在JavaSpring实现异步执行(详细篇)》Spring框架通过@Async、Executor等实现异步执行,提升系统性能与响应速度,支持自定义线程池管理并发,本文给大家介绍如何在Sprin... 目录前言1. 使用 @Async 实现异步执行1.1 启用异步执行支持1.2 创建异步方法1.3 调用

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

Spring Boot Maven 插件如何构建可执行 JAR 的核心配置

《SpringBootMaven插件如何构建可执行JAR的核心配置》SpringBoot核心Maven插件,用于生成可执行JAR/WAR,内置服务器简化部署,支持热部署、多环境配置及依赖管理... 目录前言一、插件的核心功能与目标1.1 插件的定位1.2 插件的 Goals(目标)1.3 插件定位1.4 核