最近面试,同事给面试者出了一道算法题,饶有兴趣,做了一下实现。
题目:
数字K有M位,取其N位,使取得的值为最小值(最大值)。例如:K=21456,M=5,N=3,则最大值MAX=456,最小值MIN=145。
因求最大值和最小值思路完全一致,所以以下以最小值为例。
解题思路:
算法首先想到的是效率问题,即时间效率和辅助内存效率。所以像全排列的做法肯定是不可取的。
要确定M位中最小(最大)的N位数,首先是要取得最大的位数N上的数字,例子中的数字21456如果去3位数,那么第三位即百位数可取的有2、1、4三个数字,其中1是最小值,取之。然后是N-1位即第2位上的数字,因为取的第一位是1即第4位上的值,所以N-1位即第2位的取值范围为:4和5,比较4和5,则得出最小值为4,取之。然后是N-2位即第1位上的数字,因为取的第二位是4,所以N-2位即第1位的取值范围为:5和6,比较5和6,则得出最小值为5,取之。最终得到最小值为145。
当然这个算法首先要分解数字,将各个位上的数字拆解开,这属于基本的数字拆分算法,在这里就不详细说明了。上代码:
代码:
效率分析:
时间效率分析:
用假设法推导,假设数字K,M=6,有以下推断:
N 最坏情况 最好情况
1 6(随意) 6(随意)
2 5+5=10(123456) 5+1=6(654321)
3 4+4+4=12(123456) 4+1+1=6(654321)
4 3+3+3+3=12(123456) 3+1+1+1=6(654321)
5 2+2+2+2+2=10(123456) 2+1+1+1+1=6(654321)
6 1(随意) 1(随意)
经以上可推出:
最坏情况:G(m,n) = n*(m-n+1)
最好情况:G(m,n) = m
平均情况:G(m,n) = (n*(m-n+1)+m)/2
用大O表示法:
当m无限大时,G(m,n) = O(m)
当m和n同时无限大时,G(m,n) = O(m)
所以推出,此算法的时间级位O(m)
辅助内存效率分析:
此算法用到的辅助内存为HashMap,因为和需要拆分为m个Entery元素,所以,辅助内存级别也为O(m)