字典序(头条校招java)

来源:互联网 发布:英雄联盟t恤淘宝 编辑:程序博客网 时间:2024/05/16 13:53

1、题目:

题目描述

给定整数n和m, 将1到n的这n个整数按字典序排列之后, 求其中的第m个数。
对于n=11, m=4, 按字典序排列依次为1, 10, 11, 2, 3, 4, 5, 6, 7, 8, 9, 因此第4个数是2. 
对于n=200, m=25, 按字典序排列依次为1 10 100 101 102 103 104 105 106 107 108 109 11 110 111 112 113 114 115 116 117 118 119 12 120 121 122 123 124 125 126 127 128 129 13 130 131 132 133 134 135 136 137 138 139 14 140 141 142 143 144 145 146 147 148 149 15 150 151 152 153 154 155 156 157 158 159 16 160 161 162 163 164 165 166 167 168 169 17 170 171 172 173 174 175 176 177 178 179 18 180 181 182 183 184 185 186 187 188 189 19 190 191 192 193 194 195 196 197 198 199 2 20 200 21 22 23 24 25 26 27 28 29 3 30 31 32 33 34 35 36 37 38 39 4 40 41 42 43 44 45 46 47 48 49 5 50 51 52 53 54 55 56 57 58 59 6 60 61 62 63 64 65 66 67 68 69 7 70 71 72 73 74 75 76 77 78 79 8 80 81 82 83 84 85 86 87 88 89 9 90 91 92 93 94 95 96 97 98 99 因此第25个数是120…

输入描述:

输入仅包含两个整数n和m。数据范围: 对于20%的数据, 1 <= m <= n <= 5 ; 对于80%的数据, 1 <= m <= n <= 10^7 ; 对于100%的数据, 1 <= m <= n <= 10^18.

输出描述:

输出仅包括一行, 即所求排列中的第m个数字.
示例1

输入

11 4

输出

2



2、思想:

(1)最容易想到的思路就是用一个list存储从1到n的所有数字,当然这些数字的存储格式为string,这样存好后就只能直接进行排序,从而直接获取第m位置处的数字,然而内存溢出。

(2)既然存储所有的数字会内存溢出,那么就想一个尽量占用较少内存的方法,看了看数字规律,我就写了一下,始终用一个StringBuilder来存储当前的数字,且用一个变量count存储当前已经找到了几个数字,通过判定count!=0来继续进行查找。是比(1)方法好一些,但内存还是溢出来。所有就开始看别人的代码了,也就是方法(3)

(3)四个变量:m,num,start,end,分别表示:m就是输入的m;num表示范围为[start,end)时,这个范围区间可以表示的字典序数字个数是多少;start表示区间的开始(包含),end表示区间的结束(不包含)。



3、code:

(1)内存溢出,通过率50%

package schooloffer17;import java.util.*;/** * @Author: cxh * @CreateTime: 17/11/21 15:28 * @ProjectName: JavaBaseTest * <字典排序></> * 内存超限 50% */public class DictionaryOrder {    public static void main(String[] args) {        int n,m;        Scanner scanner=new Scanner(System.in);        while (scanner.hasNextInt()){            n=scanner.nextInt();//n个数字排序            m=scanner.nextInt();//查找排序后的第m个数字            ArrayList<String> list=new ArrayList<String>();            for(int i=0;i<n;i++)                list.add(String.valueOf(i+1));            Collections.sort(list);            //输出list            System.out.println(list.get(m-1));        }    }}


(2)内存溢出,通过率60%

public class DictionaryOrder {    public static void main(String[] args) {        int n,m;        Scanner scanner=new Scanner(System.in);        while (scanner.hasNextInt()){            n=scanner.nextInt();//n个数字排序            m=scanner.nextInt();//查找排序后的第m个数字            int len=String.valueOf(n).length();//求n的位数            int count=m;//记录找出的数字个数            StringBuilder from=new StringBuilder("1");            while (count>0){                StringBuilder tmp=new StringBuilder(from);//保存from原值                int tmpNum=Integer.valueOf(tmp.toString());//保存from原值                count--;                //加0                for(int i=1;i<len && count>0;i++){                    from.append("0");                    count--;                }                //加0个数                for(int i=len-1;i>=1 && count>0;i--){//为tmp增加i个0                    if(i!=len-1)                        from=appendZero(tmp,i);                    long num=Long.valueOf(from.toString());                    while (num<=n && count>0){//为num依次增加1                        num++;                        //如果num位数出现0,去除尾部的0                        if(num%10==0){                            String str=String.valueOf(num);                            int j;                            for(j=str.length()-2;j>=0;j--){                                if(str.charAt(j)!='0')                                    break;                            }                            from.delete(0,from.length());                            from.append(str.substring(0,j+1));                            count--;                            //为尾部重新加0                            int fromLen=from.length();                            for(j=0;j<len-fromLen && count>0;j++){                                from.append("0");                                if(Integer.valueOf(from.toString())<=n)                                    count--;                                else {                                    from.delete(from.length() - 1, from.length());                                    break;                                }                            }                        }else{                            if(num<=n){                                from.delete(0,from.length());                                from.append(String.valueOf(num));                                count--;                            }                        }                    }                }                //更新from起始值                if(count>0){                    from.delete(0,from.length());                    from.append(String.valueOf(tmpNum+1));                }            }            System.out.println(from.toString());        }    }    private static StringBuilder appendZero(StringBuilder sb,int count){        for(int i=0;i<count;i++)            sb.append("0");        return sb;    }}


(3)已a

package schooloffer17;import java.util.*;/** * @Author: cxh * @CreateTime: 17/11/21 15:28 * @ProjectName: JavaBaseTest * <字典排序></> * 内存超限 50% */public class DictionaryOrder {    public static void main(String[] args) {        long n,m;        Scanner scanner=new Scanner(System.in);        while (scanner.hasNextLong()) {            n = scanner.nextLong();//n个数字排序            m = scanner.nextLong();//查找排序后的第m个数字            long res = 1;//从1开始数            m--;            while(m!=0){                long num = 0;                long start = res,end = res+1;//start和end分别表示范围的左右边界[start,end)                while(start<=n){                    num += Math.min(n+1,end)-start;//[start,end)这个范围内可以有多少个数字                    start*=10;                    end*=10;                }                if(num>m){ //如果可以表示的数字个数比还需要计算的数字个数少,则进入递归,也就是通过在res后面补0进行范围查找.                    res *= 10;                    m--;//res*10作为此次找到的第一个数字,故还需要计算的数字个数需要减一                }else{                    m-=num;//既然还需要查找的数字个数比当前范围的数字个数大,那么res通过++更改前缀,从而更改范围;同时m还需要减去当前范围内已经找到的数字个数num.                    res++;                }            }            System.out.println(res);        }    }}


原创粉丝点击