获取不存在于某集合的大小至少为某整数的最小整数

题:获取大小至少为startNo,并且不存在于某个不确定是否有序的整数数组Array中的,最小整数。

如:不存在于2,6,8,11中的不小于3的最小整数为3。

如下测试代码,未发现实现不对。。。

    public static final String timeDifferenceFormats[] = { "天", "小时", "分钟", "秒" };
    public static final String timeDifferenceFormat = "+[d天][k小时][m分钟][s秒]";

    public static StringBuilder formatTimeDifference(String fmts[], long differenceInMillis) {
        StringBuilder sb = new StringBuilder();
        long seconds = differenceInMillis / 1000;
        if (differenceInMillis > 60 * 1000) {
            long minutes = differenceInMillis / (60 * 1000);
            if (differenceInMillis > 60 * 60 * 1000) {
                long hours = differenceInMillis / (60 * 60 * 1000);
                if (differenceInMillis > 24 * 60 * 60 * 1000) {
                    long days = differenceInMillis / (24 * 60 * 60 * 1000);
                    sb.append(days).append("天");
                }
                sb.append(hours % 24).append("小时");
            }
            sb.append(minutes % 60).append("分钟");
        }
        return sb.append(seconds % 60).append("秒");
    }

    public static void main(String[] args) {
        long now = System.currentTimeMillis();
        System.out.println(now);
        String[] fmts = { "天", "小时", "分钟", "秒" };
        System.out.println(formatTimeDifference(fmts, 62000));
        java.util.Calendar calendar = java.util.Calendar.getInstance();
        calendar.setTimeInMillis(now);
        System.out.println(calendar.get(java.util.Calendar.DAY_OF_YEAR));
        System.out.println(new java.text.SimpleDateFormat("D天k小时m分钟s秒").format(new java.util.Date(now)));
        DecimalFormat df = new DecimalFormat(",###");
        System.out.println(df.format(now));

        int[] data1 = { 8899, 9, 2, 11, 1, 100 }; // 1, 2, 9, 11, 100, 8899
        int[] data2 = { 1, 3, 4, 9, 6, 2 }; // 1, 2, 3, 4, 6, 9
        int[] data3 = { 3 }; // 3
        int[] data4 = { 3, 6 }; // 3, 6
        System.out.println("1. min cave number = " + findMinCaveNumber(2, data1, false)); //3
        System.out.println("2. min cave number = " + findMinCaveNumber(2, data2, false)); //5
        System.out.println("3. min cave number = " + findMinCaveNumber(2, data3, false)); //2
        System.out.println("4. min cave number = " + findMinCaveNumber(5, data4, true)); //5
    }

    /**
     * data[leftIndex] <= start < data[rightIndex]
     *
     * @param start
     *            起始基值
     * @param data
     * @param leftIndex
     * @param rightIndex
     * @return data[leftIndex] + 1 or start
     */
    private static int findMinCaveNumberBetween(int startNo, int[] data, int leftIndex, int rightIndex) {
        //前后两个数时
        if (rightIndex - leftIndex <= 1) {
            int expectedCaveNumber = data[leftIndex] + 1;
            return expectedCaveNumber < startNo ? startNo : expectedCaveNumber;
        }
        int midIndex = (leftIndex + rightIndex) / 2;
        if (startNo < data[midIndex] && data[midIndex] - data[leftIndex] > midIndex - leftIndex) {
            return findMinCaveNumberBetween(startNo, data, leftIndex, midIndex);
        }
        return findMinCaveNumberBetween(startNo, data, midIndex, rightIndex);
    }

    /**
     *
     * @param data
     * @param start
     *            起始基值
     * @param isOrderly
     *            data是有序吗
     * @return
     */
    private static int findMinCaveNumber(int start, int[] data, boolean isOrderly) {
        if (data.length == 0) {
            return start;
        }
        if (!isOrderly) {
            Arrays.sort(data);
        }
        int min = data[0], max = data[data.length - 1];
        if (start < min || start > max) {
            return start;
        } else if (start == max || max - min == data.length -1){
            return start + 1;
        }
        else {
            //min <= start < max && max - min >= data.length (data.length must >= 2)
            return findMinCaveNumberBetween(start, data, 0, data.length -1);
        }
    }

1405643181082
1分钟2秒
199
199天8小时26分钟21秒
1,405,643,181,082
1. min cave number = 3
2. min cave number = 5
3. min cave number = 4
4. min cave number = 5

顺便记录网上一个,漏一个整数的连续集合问题:

找出所缺的整数

题目:数组A中包含n-1个[0,n-1]内的不同整数,n个数中只有一个数不在所给的数组中。设计一个找到这个数的O(n)时间的算法。除了数组A自身以外,只能利用O(1)的额外空间。

与之相似的另一个题目见《算法导论》思考题4-2:问题同上,但在这里,不能由一个单一操作来访问A中的一个完整整数,因为A中整数是以二进制表示的。我们所能用的唯一操作就是“取A[i]的第j位”,这个操作所花时间为常数。题目要求:证明如果仅用此操作,仍能在O(n)时间内找出所缺整数。

第一个题目可以想出以下几种方法:

解法一:[0,n-1]这个区间中所有整数的和不变,为n*(n-1)/2,对数组A中的所有元素求和,设为s,则丢失的整数就是n*(n-1)/2 – s。

解法二:异或运算。异或是个非常神奇的运算。设所缺的整数为k,[0,n-1]区间中所有n个数的异或结果为s(n),异或运算满足交换率和结合率,所以s(n)可以被看作[0,n-1]中去掉k外的另外n-1个数的异或结果s(n-1)和k的异或。也即:s(n)=s(n-1)^k,我们给等式两边同时异或s(n-1),等式变成了:s(n-1)^s(n)=s(n-1)^s(n-1)^k=k。而且,很明显s(n-1)其实就是数组A中所有元素的异或。所以,解法二就是:求出[0,n-1]内所有整数的异或结果s,再求出数组A中所有元素的异或结果t,所缺的整数就是s异或t。

解法三:因为A自身也有n-1个位置。可以把A作为一个散列表,这样做虽然能够得到结果,但是破坏了数组A。

至于《算法导论》思考题4-2的解法,在《算法艺术与信息学竞赛》上有解答。思路简述:自然数顺序的二进制表示最低位总是0和1交替出现,所以,首先读取数组A中所有元素的最低二进制位,如果得到的0和1的个数一样多,则说明所缺整数的最低二进制位为0,否则,哪个少,所缺整数的最低二进制位就是哪个。比如,我们得到所缺整数的最低二进制位为0,那么,说明数组A中最低二进制位为1的那些整数已经与此题无干,只需要在那些最低位为0的整数中找所缺整数。所以,时间复杂度是:T(n)=T(n/2)+n,计算:

对n的上取整或下取整不影响时间复杂度。即T(n)=O(n)。

获取不存在于某集合的大小至少为某整数的最小整数

时间: 2024-10-07 22:21:10

获取不存在于某集合的大小至少为某整数的最小整数的相关文章

纯JAVA环境获取APK信息(包名,版本,版本号,大小,权限...),纯JAVA语言编写PC端获取APK信息

纯JAVA环境获取APK信息:包名,版本,版本号,大小,权限... 纯Java环境获取APK信息需要两个包:AXMLPrinter2.jar 跟jdom.jar,用于反编译XML和解析XML的 项目目录 这个类是获取APK信息的 public class ApkUtil { private static final Namespace NS = Namespace.getNamespace("http://schemas.android.com/apk/res/android"); @

js兼容ie获取上传excel文件名称以及大小,绝对路径

/**  *   * @param obj file对象 document.getElementById(elementId);  * @returns  */ function getExcelFileFullPath(obj){ if (obj){ // ie if (window.navigator.userAgent.indexOf("MSIE") >= 1){ obj.select(); return document.selection.createRange().t

reuqest获取服务器一些信息方法集合 java

request.getServletContext().getRealPath("/")  获取项目所在服务器的全路径,如:D:\Program Files\apache-tomcat-7.0.25\webapps\TestSytem\ request.getServletPath()    获取客户端请求的路径名,如:/object/delObject request.getServerName()    获取服务器地址,如:localhost request.getServerPo

使用html元素的getBoundingClientRect来获取dom元素的时时位置和大小

使用: var section = $('.section'):这是jquery包装的dom元素,其他前端框架返回的可能也是一个包装元素, 我们需要获得的是里面的html的dom元素 然后:section[0]: 获得html的dom元素 然后: 使用section[0].getBoundingClientRect来获取该元素的时时位置和大小

C# API 获取系统DPI缩放倍数跟分辨率大小

原文:C# API 获取系统DPI缩放倍数跟分辨率大小 using System; using System.Drawing; using System.Runtime.InteropServices; namespace XYDES { public class PrimaryScreen { #region Win32 API [DllImport("user32.dll")] static extern IntPtr GetDC(IntPtr ptr); [DllImport(&

SQL0286N 找不到页大小至少为 &quot;8192&quot;、许可使用授权标识 &quot;db2inst&quot; 的缺省表空间。

在 SQL 处理期间,它返回: SQL0286N  找不到页大小至少为 "8192".许可使用授权标识 "db2inst" 的缺省表空间. 顾名思义,DB2默认的页大小是4K,这样的表的字段太长,接近8K.一条记录不能跨页存储. 所以我们需要创建一个页长为8K的表空间. 首先,创建8K的缓冲池: create bufferpool ibmdefault8k IMMEDIATE  SIZE 5000 PAGESIZE 8 K ; 然后,使用该缓冲池创建一个表空间 CR

oc 获取文件夹下文件的总大小

第一种封装: -(NSInteger)getSizeOfFilePath:(NSString *)filePath{ /** 定义记录大小 */ NSInteger totalSize = 0; /** 创建一个文件管理对象 */ NSFileManager * manager = [NSFileManager defaultManager]; /**获取文件下的所有路径包括子路径 */ NSArray * subPaths = [manager subpathsAtPath:filePath]

JS获取网页宽高方法集合

JS获取网页宽高等方法的集合:document.body.clientWidth - 网页可见区域宽document.body.clientHeight - 网页可见区域高 document.body.offsetWidth - 网页可见区域宽,包括边线和滚动条的宽document.body.offsetHeight - 网页可见区域高,包括边线和滚动条的高[FF,chrom下是整个页面高,IE opera 下正常] document.body.scrollWidth - 网页总宽documen

JAVA枚举操作(获取值,转map集合)

JAVA枚举相对来说比.NET的枚举功能强大,感觉就像是一种简化版的类对象,可以有构造方法,可以重载,可以继承接口等等,但不能继承类,JAVA枚举在实际开发中应用相当频繁,以下几个封装方法在实际开发中可能用到,希望对新手有些帮助. 首先,新建一个枚举接口,为保证所有继承此接口的枚举value及description一致,便于开发使用,枚举统一接口如下. public interface EnumCommon { public int getValue(); public String getDe