【Leetcode 每日一题】1387. 将整数按权重排序
问题背景
我们将整数 x x x 的 权重 定义为按照下述规则将 x x x 变成 1 1 1 所需要的步数:
- 如果 x x x 是偶数,那么 x = x / 2 x = x / 2 x=x/2。
- 如果 x x x 是奇数,那么 x = 3 × x + 1 x = 3 \times x + 1 x=3×x+1。
比方说, x = 3 x = 3 x=3 的权重为 7 7 7。因为 3 3 3 需要 7 7 7 步变成 1 1 1( 3 → 10 → 5 → 16 → 8 → 4 → 2 → 1 3 \rightarrow 10 \rightarrow 5 \rightarrow 16 \rightarrow 8 \rightarrow 4 \rightarrow 2 \rightarrow 1 3→10→5→16→8→4→2→1)。
给你三个整数 l o lo lo, h i hi hi 和 k k k。你的任务是将区间 [ l o , h i ] [lo, hi] [lo,hi] 之间的整数按照它们的权重 升序排序 ,如果大于等于 2 2 2 个整数有 相同 的权重,那么按照数字自身的数值 升序排序 。
请你返回区间 [ l o , h i ] [lo, hi] [lo,hi] 之间的整数按权重排序后的第 k k k 个数。
注意,题目保证对于任意整数 x x x( l o ≤ x ≤ h i lo \le x \le hi lo≤x≤hi) ,它变成 1 1 1 所需要的步数是一个 32 32 32 位有符号整数。
数据约束
- 1 ≤ l o ≤ h i ≤ 1000 1 \le lo \le hi \le 1000 1≤lo≤hi≤1000
- 1 ≤ k ≤ h i − l o + 1 1 \le k \le hi - lo + 1 1≤k≤hi−lo+1
解题过程
这题的本质要求是将数组中的两个属性当作不同的标准,完成二级排序。
刻画双重标准有两种做法,一种是定义一个二维数组,把数字和权重组成一个长为二的数对,对这个数对进行排序;另一种是用两个数组分别存储数字和权重,存储权重的数组可以看作哈希表,只作为标准来使用,不参与排序。
从效率上来说,第二种方法可以预处理计算所有可能的权重,还可以避免重复后续重复计算之前已经得到的权重,是更好的方法。实际上这题数据量不是很大,选哪种方案都能搞定。
题目明确要求权重相同的按元素本身大小升序排列,其实就是要求实际排序的流程是稳定的。
常见的排序算法,包括 Java 本身提供的排序方法,归并排序 这些当然都能解决问题。但如果进一步考虑到数据规模小,计数排序 显然是最优的选择。
在这种情况下,最好不要选择不稳定的算法。
题中要求第 K K K 大的数,虽然使用非荷兰国旗问题的一般快排划分,能够在 O ( N ) O(N) O(N) 这个量级的时间下得到结果,但实际上完全没必要(仅考虑本题的话,有计数排序兜底)。
我也尝试实现了随机快排和堆排,发现要将不稳定的排序算法改造成能按多个标准排序是比较麻烦的,浪费了相当多的时间。
几分钟就做完的题,尝试改算法改了一上午还没成功,还是不折磨自己了,今天是讨厌快排的一天。
具体实现
调用 API
class Solution {private static final int MAX_N = 1010;private static final int[] memo = new int[MAX_N];public int getKth(int lo, int hi, int k) {int n = hi - lo + 1; for(int i = 0; i < n; i++) {int curIndex = i + lo;memo[curIndex] = memo[curIndex] != 0 ? memo[curIndex] : calcWeight(curIndex);}Integer[] nums = new Integer[n];Arrays.setAll(nums, i -> i + lo);Arrays.sort(nums, (o1, o2) -> memo[o1] != memo[o2] ? memo[o1] - memo[o2] : o1 - o2);return nums[k - 1];}private int calcWeight(int n) {int res = 0;while(n != 1) {if((n & 1) == 1) {n = 3 * n + 1;} else {n >>>= 1;}res++;}return res;}
}
归并排序
class Solution {private static final int MAX_N = 1010;private static final int[] memo = new int[MAX_N];private static final int[] temp = new int[MAX_N];public int getKth(int lo, int hi, int k) {int n = hi - lo + 1; for(int i = 0; i < n; i++) {int curIndex = i + lo;memo[curIndex] = memo[curIndex] != 0 ? memo[curIndex] : calcWeight(curIndex);}int[] nums = new int[n];Arrays.setAll(nums, i -> i + lo);mergeSort(nums, 0, n - 1);return nums[k - 1];}private int calcWeight(int n) {int res = 0;while(n != 1) {if((n & 1) == 1) {n = 3 * n + 1;} else {n >>>= 1;}res++;}return res;}private void merge(int[] arr, int left, int mid, int right) {int index1 = left, index2 = mid + 1, index = left;while(index1 <= mid && index2 <= right) {temp[index++] = memo[arr[index1]] <= memo[arr[index2]] ? arr[index1++] : arr[index2++];}while(index1 <= mid) {temp[index++] = arr[index1++];}while(index2 <= right) {temp[index++] = arr[index2++];}System.arraycopy(temp, left, arr, left, right - left + 1);}private void mergeSort(int[] arr, int left, int right) {if(left == right) {return;}int mid = left + ((right - left) >>> 1);mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, mid, right);}
}
计数排序
class Solution {private static final int MAX_N = 1010;private static final int[] memo = new int[MAX_N];public int getKth(int lo, int hi, int k) {int n = hi - lo + 1; for(int i = 0; i < n; i++) {int curIndex = i + lo;memo[curIndex] = memo[curIndex] != 0 ? memo[curIndex] : calcWeight(curIndex);}int[] nums = new int[n];Arrays.setAll(nums, i -> i + lo);countingSort(nums);return nums[k - 1];}private int calcWeight(int n) {int res = 0;while(n != 1) {if((n & 1) == 1) {n = 3 * n + 1;} else {n >>>= 1;}res++;}return res;}private void countingSort(int[] arr) {int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;for(int item : arr) {min = Math.min(min, memo[item]);max = Math.max(max, memo[item]);}int range = max - min + 1;int[] count = new int[range];for(int item : arr) {count[memo[item] - min]++;}for(int i = 1; i < count.length; i++) {count[i] += count[i - 1];}int[] res = new int[arr.length];for(int i = arr.length - 1; i >= 0; i--) {int cur = arr[i];res[--count[memo[cur] - min]] = cur;}System.arraycopy(res, 0, arr, 0, arr.length);}
}
相关文章:
【Leetcode 每日一题】1387. 将整数按权重排序
问题背景 我们将整数 x x x 的 权重 定义为按照下述规则将 x x x 变成 1 1 1 所需要的步数: 如果 x x x 是偶数,那么 x x / 2 x x / 2 xx/2。如果 x x x 是奇数,那么 x 3 x 1 x 3 \times x 1 x3x1。 比方说, x …...
科研笔记 KDD 2025
1 基本介绍 KDD 每年有多次投稿周期。KDD 2025 将有两个截止时间:分别是 2024 年 8 月 1 日和 2025 年 2 月 1 日(全文提交截止时间在摘要提交截止后一周)。 同时,KDD 会议论文集(Proceedings)将分两批出…...
黑马Java面试教程_P8_并发编程
系列博客目录 文章目录 系列博客目录前言1.线程的基础知识1.1 线程和进程的区别?难2频3面试文稿 1.2 并行和并发有什么区别? 难1频1面试文稿 1.3 创建线程的四种方式 难2频4面试文稿 1.4 runnable 和 callable 有什么区别 难2频3面试文稿 1.5 线程的 run…...
网络视频监控平台/安防监控/视频综合管理Liveweb视频汇聚平台解决方案
一、当前现状分析 当前视频资源面临以下问题: 1)不同单位在视频平台建设中以所属领域为单位,设备品牌众多,存在的标准不一,各系统之间也没有统一标准; 2)各单位视频平台建设分散、统筹性差&am…...
workman服务端开发模式-应用开发-后端api推送修改二
需要修改两个地方,第一个是总控制里面的续token延时,第二个是操作日志记录 一、总控续token延时方法 在根目录下app文件夹下controller文件夹下Base.php中修改isLoginAuth方法,具体代码如下: <?php /*** 总控制* User: 龙哥…...
SQL 使用带聚集函数的联结
聚集函数用于汇总数据,通常用于从一个表中计算统计信息,但也可以与联结一起使用。以下是一个例子,展示如何使用聚集函数统计每个顾客的订单数。 示例 1:使用 COUNT() 函数与 INNER JOIN 假设我们需要检索所有顾客及每个顾客所下…...
Restaurants WebAPI(三)——Serilog/FluenValidation
文章目录 项目地址一、Serilog使用1.1 安装 Serilog1.2 注册日志服务1.3 设置日志级别和详情1.4 配置到文件里1.5 给不同的环境配置日志1.5.1 配置appsettings.Development.json二、Swagger的使用三、自定义Exception中间件3.1 使用FluentValidation项目地址 教程作者:教程地址…...
概率论得学习和整理32: 用EXCEL描述正态分布,用δ求累计概率,以及已知概率求X的区间
目录 1 正态分布相关 2 正态分布的函数和曲线 2.1 正态分布的函数值,用norm.dist() 函数求 2.2 正态分布的pdf 和 cdf 2.3 正态分布的图形随着u 和 δ^2的变化 3 正态分布最重要的3δ原则 3.0 注意,这里说的概率一定是累计概率CDF,而…...
【原生js案例】让你的移动页面实现自定义的上拉加载和下拉刷新
目前很多前端UI都是自带有上拉加载和下拉刷新功能,按照官网配置去实现即可,比如原生小程序,vantUI等UI框架,都替我们实现了内部功能。 那如何自己来实现一个上拉加载和下拉刷新的功能? 实现效果 不用浏览器的css滚动条,自定义实现滚动效果 自定义实现滚动,添加上拉加载…...
【linux 常用命令】
1. 使用xshell 通过SSH连接到Linux服务器 ssh -p 端口号 usernameip地址2. 查看当前目录下的子文件夹的内存占用情况 du -a -h -d 1或者 du -ah -d 1-a :展示所有子文件夹(包括隐藏文件夹),-h :以人类可读的形式&am…...
【JetPack】Room数据库笔记
Room数据库笔记 ORM框架:对齐数据库数据结构与面向对象数据结构之间的关系,使开发编程只考虑面向对象不需要考虑数据库的结构 Entity : 数据实体,对应数据库中的表 <完成面向对象与数据库表结构的映射> 注解: 类添加注解…...
【CSS in Depth 2 精译_088】第五部分:添加动效概述 + 第 15 章:CSS 过渡特效概述 + 15.1:状态间的由此及彼
当前内容所在位置(可进入专栏查看其他译好的章节内容) 第五部分 添加动效 ✔️【第 15 章 过渡】 ✔️ 15.1 状态间的由此及彼 ✔️15.2 定时函数 文章目录 第 5 部分 添加动效 Adding motion第 15 章 过渡 Transitions15.1 状态间的由此及彼 From here…...
# 起步专用 - 哔哩哔哩全模块超还原设计!(内含接口文档、数据库设计)
↑ 上方下载文档 (大小374KB) 接口文档预览 (超过50个接口) 一、数据库25张表er-关系清晰构图!(tip: 鼠标右键图片 > 放大图像) 二、难点/经验 详细说明 热门评论排序评论点赞列表|DTO封装经验分享|精华接口文档说明 组员都说喜欢分档对应枚举码 如果这篇文章…...
[机器学习]XGBoost(3)——确定树的结构
XGBoost的目标函数详见[机器学习]XGBoost(2)——目标函数(公式详解) 确定树的结构 之前在关于目标函数的计算中,均假设树的结构是确定的,但实际上,当划分条件不同时,叶子节点包含的…...
PHP阶段一
PHP 一门编程语言 运行在服务器端 专门用户开发网站的 脚本后缀名.php 与HTML语言进行混编,脚本后缀依然是.php 解释型语言,不要编译直接运行 PHP运行需要环境: Windows phpstudy Linux 单独安装 Web 原理简述 1、打开浏览器 2、输入u…...
用人话讲计算机:Python篇!(十五)迭代器、生成器、装饰器
一、迭代器 (1)定义 标准解释:迭代器是 Python 中实现了迭代协议的对象,即提供__iter__()和 __next__()方法,任何实现了这两个方法的对象都可以被称为迭代器。 所谓__iter__(),即返回迭代器自身 所谓__…...
5G -- 5G网络架构
5G组网场景 从4G到5G的网络演进: 1、UE -> 4G基站 -> 4G核心网 * 部署初中期,利用存量网络,引入5G基站,4G与5G基站并存 2、UE -> (4G基站、5G基站) -> 4G核心网 * 部署中后期,引入5G核心网&am…...
VR线上展厅的色彩管理如何影响用户情绪?
VR线上展厅的色彩管理对用户情绪的影响是多方面的,以下是专业从事VR线上展厅制作的圆桌3D云展厅平台为大家介绍的一些关键点: 情感共鸣:色彩能够激发特定的情感反应。例如,暖色调(如红色、橙色)通常与活力和…...
Vue3:uv-upload图片上传
效果图: 参考文档: Upload 上传 | 我的资料管理-uv-ui 是全面兼容vue32、nvue、app、h5、小程序等多端的uni-app生态框架 (uvui.cn) 代码: <view class"greenBtn_zw2" click"handleAddGroup">添加班级群</vie…...
大数据机器学习算法和计算机视觉应用07:机器学习
Machine Learning Goal of Machine LearningLinear ClassificationSolutionNumerical output example: linear regressionStochastic Gradient DescentMatrix Acceleration Goal of Machine Learning 机器学习的目标 假设现在有一组数据 x i , y i {x_i,y_i} xi,yi&…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...
莫兰迪高级灰总结计划简约商务通用PPT模版
莫兰迪高级灰总结计划简约商务通用PPT模版,莫兰迪调色板清新简约工作汇报PPT模版,莫兰迪时尚风极简设计PPT模版,大学生毕业论文答辩PPT模版,莫兰迪配色总结计划简约商务通用PPT模版,莫兰迪商务汇报PPT模版,…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
