题目:在非负数组(乱序)中找到最小的可分配的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. margin:auto你真的理解么?

    含义 margin:auto是具有强烈计算意味的关键字,用来计算元素对应方向应该获得的剩余空间大小 填充规则 (1) 如果一侧定值,一侧auto,则auto为剩余空间大小 (2) 如果两侧均是auto ...

  2. php 获取用户的IP、地址、来源

    js方法获取用户的 ip 和 地址 <script src="http://pv.sohu.com/cityjson?ie=utf-8"></script> ...

  3. pip的安装问题

    1. pip install 要不要加 sudo 不加sudo经常会遇到权限问题,如: $ pip install robotframeworklexer Collecting robotframew ...

  4. AI阅粒app

    项目架构 前端 lve 后端 php+flask 实现的功能 在app底栏上有首页,标签,评论,和我的.能够通过首页浏览文章,通过标签查看对应的文章,每个标签里边的文章底下都有对应的评论数,浏览人数, ...

  5. Justoj 2389: 拼接三角形 二分查找

    2389: 拼接三角形 时间限制: C/C++ 1 s      Java/Python 3 s      内存限制: 128 MB      答案正确: 7      提交: 21 提交 我的状态 ...

  6. .Net 操作证书文件

    一..Net加签与验签.经过测试,发现使用同一套私钥和公钥,JAVA和.Net可以实现互通 1.1 私钥加签 公钥验签 public void Encode() { try { var path = ...

  7. .net core 2.x - docker(for windows)-linux配置及项目+SqlServer发布

    将.net core2.x+sqlserver项目发布到docker.呵呵,操作很自如,如下. 1.罗嗦几句 在跑起来之前浪费了不少时间和精力,起初是将docker for windows的环境转换成 ...

  8. zabbix编译安装

    第一部分zabbix安装部署,实现分布式监控及网络知识 #yum install  lrzsz.x86_64   传送文件 安装mysql脚本 #!/bin/bash DIR = pwd NAME = ...

  9. SeaJS之use方法

    SeaJS 是一个js模块加载器.在 SeaJS 看来,一个文件就是一个模块.所有模块都遵循 CMD 规范 define(function(require, exports, module) { va ...

  10. UOJ#196. 【ZJOI2016】线段树 概率期望,动态规划

    原文链接www.cnblogs.com/zhouzhendong/p/UOJ196.html 题解 先离散化,设离散化后的值域为 $[0,m]$ . 首先把问题转化一下,变成:对于每一个位置 $i$ ...