[Leedcode][JAVA]第[945]题

【问题描述】

给定整数数组 A,每次 move 操作将会选择任意 A[i],并将其递增 1。返回使 A 中的每个值都是唯一的最少操作次数。示例 1:输入:[1,2,2]
输出:1
解释:经过一次 move 操作,数组将变为 [1, 2, 3]。
示例 2:输入:[3,2,1,2,1,7]
输出:6
解释:经过 6 次 move 操作,数组将变为 [3, 4, 1, 2, 5, 7]。
可以看出 5 次或 5 次以下的 move 操作是不能让数组的每个值唯一的。
提示:0 <= A.length <= 40000
0 <= A[i] < 40000

【解答思路】

1. 排序 O(NlogN)

先排序,再依次遍历数组元素,若当前元素小于等于它前一个元素,则将其变为前一个数+1。

class Solution {public int minIncrementForUnique(int[] A) {// 先排序Arrays.sort(A);int move = 0;// 遍历数组,若当前元素小于等于它的前一个元素,则将其变为前一个数+1for (int i = 1; i < A.length; i++) {if (A[i] <= A[i - 1]) {int pre = A[i];A[i] = A[i - 1] + 1;move += A[i] - pre;}}return move;}}
2. 注意最后一个的推导 计数排序 O(N)
class Solution {public int minIncrementForUnique(int[] A) {// counter数组统计每个数字的个数。//(这里为了防止下面遍历counter的时候每次都走到40000,所以设置了一个max,这个数据量不设也行,再额外设置min也行)int[] counter = new int[40001];int max = -1;for (int num: A) {counter[num]++;max = Math.max(max, num);}// 遍历counter数组,若当前数字的个数cnt大于1个,则只留下1个,其他的cnt-1个后移int move = 0;for (int num = 0; num <= max; num++) {if (counter[num] > 1) {int d = counter[num] - 1;move += d;counter[num + 1] += d;}}// 最后, counter[max+1]里可能会有从counter[max]后移过来的,counter[max+1]里只留下1个,其它的d个后移。// 设 max+1 = x,那么后面的d个数就是[x+1,x+2,x+3,...,x+d],// 因此操作次数是[1,2,3,...,d],用求和公式求和。int d = counter[max + 1] - 1;move += (1 + d) * d / 2;return move;}
}
3. 线性探测法(含路径压缩) O(N) 神仙解法
  • 把原数组映射到一个地址不冲突的区域 ,和解决hash冲突的线性探测法比较相似
  • 直接线性探测可能会由于冲突导致反复探测耗时太长 -> 考虑探测的过程中进行路径压缩
  • 经过某条路径最终探测到一个空位置x后,将这条路径上的值都变成空位置所在的下标x,那么假如下次探测的点又是这条路径上的点,则可以直接跳转到这次探测到的空位置x,从x开始继续探测。

下面用样例2:[3, 2, 1, 2, 1, 7],来模拟一遍线性探测的过程。

模拟的过程中用int move来记录操作数(即要求的增量数)。

step1: 插入3:

image

因为3的位置是空的,所以直接放入3即可。(此时数组变成了上图,红色表示本次的更改)

move = 0 保持不变;

step2: 插入2:

image

因为2的位置是空的,所以直接放入2即可。(此时数组变成了上图,红色表示本次的更改)

move = 0 保持不变;

step3: 插入1:

image

因为1的位置是空的,所以直接放入1即可。(此时数组变成了上图,红色表示本次的更改)

move = 0 保持不变;

step4: 插入2:

image

此时我们发现2的位置已经有值了,于是继续向后探测,直到找到空位4,于是2映射到了4。

⚠️并且!!我们要对刚刚走过的路径2->3->4进行压缩,即将他们的值都设置为本次探测到的空位4(那么下次探测就可以直接从4往后找了~~)。

(此时数组变成了上图,红色表示本次的更改)

move = move + 4 - 2 = 2;

step5: 插入1:

image

此时我们发现1的位置已经有值了,于是向后探测,探测到了2,发现2的位置也有值了,但是由于2在上次的过程中存了上次的空位4,所以我们直接跳转到4+1即从5开始探测就行了(而不需要重复走一遍2->3->4这条路径喽!),此时我们发现5是个空位,因此将1映射到5,并且对刚刚走过的路径1->2->5进行路径压缩 即 使其都映射到5!

(此时数组变成了上图,红色表示本次的更改)

move = move + 5 - 1 = 6;

step6: 插入7:

image

因为7的位置是空的,所以直接放入7即可。(此时数组变成了上图,红色表示本次的更改)

move = 6 保持不变;

以上,最终move为6。

class Solution {int[] pos = new int [80000];public int minIncrementForUnique(int[] A) {Arrays.fill(pos, -1); // -1表示空位int move = 0;// 遍历每个数字a对其寻地址得到位置b, b比a的增量就是操作数。for (int a: A) {int b = findPos(a); move += b - a;}return move;}// 线性探测寻址(含路径压缩)private int findPos(int a) {int b = pos[a];// 如果a对应的位置pos[a]是空位,直接放入即可。if (b == -1) { pos[a] = a;return a;}// 否则向后寻址// 因为pos[a]中标记了上次寻址得到的空位,因此从pos[a]+1开始寻址就行了(不需要从a+1开始)。b = findPos(b + 1); //递归pos[a] = b; // ⚠️寻址后的新空位要重新赋值给pos[a]哦,路径压缩就是体现在这里。return b;}
}
4. 贪心算法 时间复杂度:O(Nlog N) 空间复杂度:O(1)
 public int minIncrementForUnique(int[] A) {int len = A.length;if (len == 0) {return 0;}Arrays.sort(A);// 打开调试// System.out.println(Arrays.toString(A));int preNum = A[0];int res = 0;for (int i = 1; i < len; i++) {// preNum + 1 表示当前数「最好」是这个值if (A[i] == preNum + 1) {preNum = A[i];} else if (A[i] > preNum + 1) {// 当前这个数已经足够大,这种情况可以合并到上一个分支preNum = A[i];} else {// A[i] < preNum + 1res += (preNum + 1 - A[i]);preNum++;}}return res;}

【总结】

  1. 思维过于局限 ,统计相同的数字分别+1,使用两层循环导致超时。
  2. 思维不跳跃,没有整体把握,第二种方法和第三种方法看了半天。

转载来自: https://leetcode-cn.com/problems/minimum-increment-to-make-array-unique/solution/ji-shu-onxian-xing-tan-ce-fa-onpai-xu-onlogn-yi-ya/

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

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

相关文章

玩转oracle 11g(37):rman备份-数据库指定文件恢复

.数据库指定数据文件恢复 启动数据库的时候报错 ORA-01157: cannot identify/lock data file 5 - see DBWR trace file ORA-01110: data file 5: D:\ORACLE\PRODUCT\10.2.0\ORADATA\DOCARE\AP MEDCOMM.DBF ORA-27041: unable to open file OSD-04002: 无法打开文件 O/S-Erro…

java xpath 解析xml_使用XPATH解析XML文件

使用XPATH解析XML文件import java.util.Iterator;import java.util.List;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Node;import org.dom4j.io.SAXReader;public class TestXPath {public static void main(String[] args) throws Docum…

并发编程-concurrent指南-原子操作类-AtomicBoolean

类AtomicBoolean 可以用原子方式更新的 boolean 值。有关原子变量属性的描述&#xff0c;请参阅 java.util.concurrent.atomic 包规范。AtomicBoolean 可用在应用程序中&#xff08;如以原子方式更新的标志&#xff09;&#xff0c;但不能用于替换 Boolean。 2.构造函数 1.Atom…

[剑指offer]面试题第[7]题[JAVA][斐波那契数列][递归]

【问题描述】 大家都知道斐波那契数列&#xff0c;现在要求输入一个整数n&#xff0c;请你输出斐波那契数列的第n项&#xff08;从0开始&#xff0c;第0项为0&#xff09;。 n<39 【解答思路】 1.递归&#xff08;面试避免&#xff09; O(n^2) public class Solution {pu…

JVM 内存设置大小(Xms Xmx PermSize MaxPermSize 区别)

Eclipse崩溃&#xff0c;错误提示&#xff1a;MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) space remains. It is strongly recommendedthat you exit and restart MyEclipse with new virtual machine memoryparamters to increase …

玩转oracle 11g(38):rman备份-全库恢复

(1)选择“开始” “运行”&#xff0c;输入cmd&#xff0c;按回车。 (2)输入“ set oracle_sidorcl”&#xff0c;按回车。 &#xff08;oracle_sid根据自己库的设置写&#xff09; (3)输入“rman target /”&#xff0c;按回车 (4)关闭数据库。输入“shutdown immediate;”…

[Leedcode][JAVA][第876题][快慢指针]

【问题描述】 给定一个带有头结点 head 的非空单链表&#xff0c;返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;[1,2,3,4,5] 输出&#xff1a;此列表中的结点 3 (序列化形式&#xff1a;[3,4,5]) 返回的结…

玩转oracle 11g(39):oracle11g密码过期后的解决方法

在使用oracle11g数据库的过程中经常会遇到密码180天过期的问题&#xff0c;这是因为oracle11g中默认在default概要文件中设置了“PASSWORD_LIFE_TIME180天”导致的&#xff0c;在此分享一个比较好用的解决办法 1、查看用户的proifle是哪个&#xff0c;一般是default&#xff1…

Django补充

django页面渲染具体流程 在django的页面渲染中&#xff0c;下面这段程序 def test1(request):return render(request,aa.html,{data:wusir}) 等同于 from django.template import loader def test1(request):html loader.get_template(aa.html)html_str html.render({data:wu…

算法复杂度-BigO表示法

1.时间复杂度--大O表示法 算法的渐进时间复杂度&#xff0c;T(n)O(f(n)) T&#xff08;n&#xff09;表示算法的渐进时间复杂度 f&#xff08;n&#xff09;表示代码执行的次数 O&#xff08;&#xff09;表示正比例关系 2.常用的时间复杂度量级 3.举例 &#xff08;1&am…

java代码连接redis_java代码连接redis

需要的maven依赖redis.clientsjedis2.9.0代码&#xff1a;package yofc;import redis.clients.jedis.Jedis;import redis.clients.jedis.JedisPool;import redis.clients.jedis.JedisPoolConfig;import java.net.URI;public class demo {private static JedisPool pool null;/…

[Leedcode][JAVA][按摩师][动态规划]

【问题描述】 一个有名的按摩师会收到源源不断的预约请求&#xff0c;每个预约都可以选择接或不接。在每次预约服务之间要有休息时间&#xff0c;因此她不能接受相邻的预约。给定一个预约请求序列&#xff0c;替按摩师找到最优的预约集合&#xff08;总预约时间最长&#xff0…

玩转oracle 11g(40):Oracle11g 不区分大小写设定

Cmd>sqlplus / as sysdba Sql>show  parameter sec_case_sensitive_logon parameter sec_case_sensitive_logon的值为“true”说明区分大小写&#xff0c;为“false”说明不区分大小写&#xff0c;当为“true”时执行以下语句 ALTER SYSTEM SET SEC_CASE_SENSITIVE_…

字串转日期

字串转日期 select date_format(concat(trans_recv_date,trans_recv_time),%Y-%m-%d %T.%f) from cc_qrcode_ride_trans limit 10;转载于:https://www.cnblogs.com/huiandong/p/10185591.html

java mtom_java-axis1.4客户端使用Mtom发送文件

我正在尝试将带有axis1.4客户端的文件发送到jaxws服务.我的客户代码如下.System.out.println(service.getCalcImplPort().getFile(new DataHandler(new DataSource() {Overridepublic OutputStream getOutputStream() throws IOException {// TODO Auto-generated method stubr…

[Leedcode][JAVA][第892题][图形题]

【问题描述】 在 N * N 的网格上&#xff0c;我们放置一些 1 * 1 * 1 的立方体。每个值 v grid[i][j] 表示 v 个正方体叠放在对应单元格 (i, j) 上。请你返回最终形体的表面积。示例 1&#xff1a;输入&#xff1a;[[2]] 输出&#xff1a;10 示例 2&#xff1a;输入&#xf…

玩转oracle 11g(41):rman备份-00554或者04005

Rman备份 补充问题&#xff1a; 在备份的时候出现如下错误&#xff1a; RMAN-00554: 内部恢复管理器程序包初始化失败 RMAN-04005: 目标数据库中存在错误: ORA-01031: 权限不足 脚本用户改成sys即可

hdu4554 A Famous Game 概率期望

题面 题意&#xff1a;n个球&#xff0c;2种颜色&#xff0c;可能有0~n个红球,每种情况的概率相同。现在从箱子里取出了$p$个球&#xff0c;其中有$Q$个是红球,问现在再取一个球是红球的概率为多少&#xff1f;题解&#xff1a;因为0 ~ n的概率相同&#xff0c;所以每个球是红色…

计算机论文搜索技巧【二】

##善用谷歌学术 ####本文以“blockchain”为例 1.创建快讯 当你确定了研究方向时&#xff0c;订阅功能会主动推送相关文章&#xff0c;是被动输入的神器 2.善用“左栏”筛选条件 3.善用文章摘要下“图标”扩展思路 如何下载文章 未完待续…

java学习(128):map类

定义一个汽车类 import java.util.Date; public class Car {private String brand;//品牌private Date createDate;private int housepower;//马力private int speed;//速度public void setBrand(String brand) {this.brand brand;}public String getBrand() {return brand;}…