题目:在非负数组(乱序)中找到最小的可分配的id(从1开始编号),数据量10000000。

题目解读:在一个不重复的乱序的自然数组中找到最小的缺失的那个数,比如1,2,3,6,4,5,8,11。那么最小可用id就为7。

代码:

import java.util.Arrays;

/**
* 解决最小可用id问题
*/
public class MinFreeId { public static void main(String[] args) { // int[]arr = {1,5,3,2,6,7,10,9,4}; // 最开始小数据测试
int []arr = new int[1000*1000];
for (int i = 0; i < arr.length; i++) {
// if(i==900000) 那解法一运行时间就太长了
if (i==90000) {
arr[i] = arr.length+10;
}else {
arr[i] = i+1;
}
}
long now = System.currentTimeMillis();
System.out.println(find1(arr));
System.out.println("解法一消耗的时间:"+(System.currentTimeMillis()-now)+"ms"); now = System.currentTimeMillis();
System.out.println(find2(arr));
System.out.println("解法二消耗的时间:"+(System.currentTimeMillis()-now)+"ms"); now = System.currentTimeMillis();
System.out.println(find3(arr));
System.out.println("解法三消耗的时间:"+(System.currentTimeMillis()-now)+"ms"); now = System.currentTimeMillis();
System.out.println(find4(arr,0,arr.length-1));
System.out.println("解法四消耗的时间:"+(System.currentTimeMillis()-now)+"ms"); } // O(n^2) 暴力解法:从1开始依次探测每个自然数是否在数组中
static int find1(int[]arr){
int i = 1;
while(true){
for (int j = 0; j < arr.length;) {
if (arr[j]==i) {
i++;
j = 0;
continue;
}else {
j++;
}
}
return i;
}
} // O(nlgn)
static int find2(int[]arr){
Arrays.sort(arr); // O(nlgn) 后续扫描时间O(N) 相比之下 取O(nlgn) 所以时间复杂度为O(nlgn)
int i = 0;
while(i<arr.length){
if (i+1!=arr[i]) { // 不存在的最小自然数
return i+1;
}
i++;
}
return i+1;
} /**
* 改进1:用辅助空间
* 有点类似计数排序 O(N)但是浪费空间
*/
static int find3(int[]arr){
int n = arr.length;
int []helper = new int[n+1];
for (int i = 0; i < n; i++) { // O(N)
if (arr[i]<n+1) {
helper[arr[i]] = 1; // 辅助空间的下标也是有用的
}
}
for (int i = 1; i <= n; i++) { // O(N) if (helper[i] == 0) {
return i;
}
}
return n+1;
} /**
* // O(N)
* 改进2:分区,递归
* 问题可转化为:n的正数的数组A,如果存在小于n的数不在数组中,必然存在大于n的数组中,否则数组排列恰好为1到n
*/ private static int find4(int[] arr, int l, int r) {
if (l>r) {
return l+1;
}
int midIndex = l+((r-l)>>1); // 中间下标
int q = SelectK.selectK(arr, l, r, midIndex-l+1); // 调用查找第k大的元素的方法
int t = midIndex + 1; // 期望值
if (q==t) { // 左侧紧密
return find4(arr,midIndex+1,r);
}else { // 左侧稀疏
return find4(arr, l, midIndex-1);
}
}
}

结果:

  

结论:根据每个解法所消耗的时间即可得出哪个解法的效率更高。所以在数据量较大的情况下最好选用O(lgn)和O(N)级别的算法,O(nlgn)次之。

最小可用id的更多相关文章

  1. mysql查询表中最小可用id值

    今天在看实验室的项目时,碰到的一个问题,.先把sql语句扔出来 // 这条语句在id没有1时,不能得到正确的查询结果. select min(id+1) from oslist c where not ...

  2. SQL-42 删除emp_no重复的记录,只保留最小的id对应的记录

    题目描述 删除emp_no重复的记录,只保留最小的id对应的记录.CREATE TABLE IF NOT EXISTS titles_test (id int(11) not null primary ...

  3. SQL server 存储过程 C#调用Windows CMD命令并返回输出结果 Mysql删除重复数据保留最小的id C# 取字符串中间文本 取字符串左边 取字符串右边 C# JSON格式数据高级用法

    create proc insertLog@Title nvarchar(50),@Contents nvarchar(max),@UserId int,@CreateTime datetimeasi ...

  4. 最小可用 Spring MVC 配置

    [最小可用 Spring MVC 配置] 1.导入有概率用到的JAR包, -> pom.xml 的更佳实践 - 1.0 <- <project xmlns="http:// ...

  5. 相同name,取最小的id的值,mysql根据相同字段 更新其它字段

    id name info1 a 1232 a 2353 a 1244 b 125 b 987相同name,取最小的id的值id name info1 a 1232 a 1233 a 1234 b 12 ...

  6. mysql删除表中重复数据,只保留一个最小的id的记录

    语句: delete from table1 where id not in (select minid from (select min(id) as minid from table1 group ...

  7. Mysql删除重复数据保留最小的id

    在网上查找删除重复数据保留id最小的数据,方法如下: DELETE FROM people WHERE peopleName IN ( SELECT peopleName FROM people GR ...

  8. Salesforce 生成测试可用 Id

    在写 Test Class 的时候,有时候需要一批有 Id 的数据或者把 Id 作为参数等情况,在数据关系比较复杂的情况下去造真实数据有些麻烦,于是找到这样一个可以生成 Id 的方法可以用来辅助测试! ...

  9. 从0移植uboot(三) _编译最小可用uboot

    前两篇介绍了uboot-2013.01的配置原理以及大体的运行流程,本文将讨论如何对uboot源码进行配置,将一个可用的uboot烧录到SD卡中. 定制自己的core board 市面上能买到的开发板 ...

随机推荐

  1. Mac 小功能

    Safari  安装扩展    https://safari-extensions.apple.com/?category=translation 关闭第三方验证  有时候打开自己下载的安装包会提示 ...

  2. lr 中cookie的解释与用法

    Loadrunner 中 cookie 解释与用法loadrunner 中与 cookie 处理相关的常用函数如下: web_add_cookie(): 添加新的 cookie 或者修改已经存在的 c ...

  3. MYSQL的安全模式:sql_safe_updates介绍

    什么是安全模式 在mysql中,如果在update和delete没有加上where条件,数据将会全部修改.不只是初识mysql的开发者会遇到这个问题,工作有一定经验的工程师难免也会忘记写入where条 ...

  4. 将最小的OWIN身份验证添加到现有的ASP.NET MVC应用程序

    https://weblog.west-wind.com/posts/2015/Apr/29/Adding-minimal-OWIN-Identity-Authentication-to-an-Exi ...

  5. Ajax 的异步调用和批量修改

    AJAX的异步调用的分层 有四个jsp页面,在index.jsp页面上 要在dataDiv出显示调用的的数据回显到此处,可以让showStudent2.jsp页面的数据回调到此处,$("#d ...

  6. 计蒜客 买书 dfs

    题目: https://www.jisuanke.com/course/2291/182236 思路: 递归解决,从第一本书开始,每本书都有两种选择: //index是book里面每本书价格的下标, ...

  7. 大数加法~HDU 1002 A + B Problem II

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1002 题意: 数学题,A+B; 思路,这个数非常大,普通加法一定会超时,所以用大数加法.大数加法的基 ...

  8. 【C语言编程练习】5.9 爱因斯坦的阶梯问题

    1. 题目要求 有一个长阶梯,每2步上,最后剩1个台阶,若每3步上,最后剩2个台阶.若每5步上,最后剩4个台阶,若每6步上,最后剩5个台阶.只有每步上7阶,才可以刚好走完,请问台阶至少有多少阶? 2. ...

  9. Redis数据库概述

    Redis数据库概述 Redis是什么 redis是一个高性能的key-value存储系统.支持的value类型相对更多,包括string,list,set,zset(sorted set --有序集 ...

  10. Python网络编程基础pdf

    Python网络编程基础(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1VGwGtMSZbE0bSZe-MBl6qA 提取码:mert 复制这段内容后打开百度网盘手 ...