腾讯- 数字排列

声明:题目来自: http://blog.csdn.net/v_JULY_v/archive/2010/11/17/6015165.aspx   JULY整理了100道微软等公司的面试题目,我想先不看答案: http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126406.aspx  自己先做一遍。

 

题目:

 

第6题
------------------------------------
腾讯面试题:  
给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数  
要求下排每个数都是先前上排那十个数在下排出现的次数。  
上排的十个数如下:  
[0,1,2,3,4,5,6,7,8,9]


初看此题,貌似很难,10分钟过去了,可能有的人,题目都还没看懂。  
举一个例子,  
数值: 0,1,2,3,4,5,6,7,8,9  
分配: 6,2,1,0,0,0,1,0,0,0  
0在下排出现了6次,1在下排出现了2次,  
2在下排出现了1次,3在下排出现了0次....  
以此类推..

 

思路:

 

说实话,第一遍看题目我还真没有看懂,看了下面的例子我才看懂的。brute-force肯定是不行的,每个位置都可以放置0-9之间的任何数,也就是说死遍历的话一共有 1010 种可能性。

 

给定的数列是[0 1 2 3 4 5 6 7 8 9], 一共10个数,10个位置,所以5,6,7,8,9 对应的位置都不可能是>=2, 原因是如果5下面放置2,意味着 5 在下面要出现2次,假设A和B下面是5,那么A要出现5次,B要出现5次,已经是10个位置被占了,如果A和B都不等于2,那么至少已经11个位置了(A5个,B5个,2 一个); 如果A=2,那B出现5次,2出现5次(其中包括5下面的那个2),这个时候6,7,8,9下面都必须是0(假设6下面是1,那5要出现2次,6要出现1次,一共11个位置了), 也就是说B=0, 好, 0 出现5次,2出现5次 --> 可能吗?无论你让除6,7,8,9外的任何数下面是2,都不成立!

 

 

所以我们得出:

 

1: 5,6,7,8,9 下面只能是0或者1, 并且只能有一个位置是1,其他的位置必须为0。

那可以让5,6,7,8,9 下面都是0吗?不行,如果这样,0就已经出现了5次,那上排0下面的数字至少是5,也就是5出现了1次,和5下面是0矛盾!也就是说:

 

2: 5,6,7,8,9 下面必须也仅有一个数字下面是1,其余都是0,上排0位置下面至少是4。

如果5,6,7,8,9之间有一个是1,那T[1] 至少是1 (我以T表示我们要得到的数列), 但是T[1]不能是1,因为T[5...9]之间已经有1个1,如果T[1]再=1, T中就有两个1,所以T[1]至少是2 ! 如果T[1]是2,则T[2]是1, 因为2出现了一次。那到目前为止:

 

T[0] >=4, T[1]=2, T[2]=1, T[5...9] 之间有1个1,4个0, 只剩T[3],T[4]没有定了。注意 T[5...9]中选中的那1个5...9放在哪里呢?有3个选择: T[0], T[3] 或者T[4] (条件是0至少4个,2一个,1两个 --> 7个位置占掉了),所以只能放在T[0], 于是:

 

T[0]=5...9, T[1]=2, T[2]=1, T[5...9] 之间1个1,4个0, 还剩两个位置T[3],T[4],放0, 所以10个位置-1个位置(5到9之间的那个1)- 2个位置(T[1]和T[2]) - 1个位置(T[0]) = 6, 0 可以放6个,所以T[0]=7, T[3]=T[4]=0.

 

所以: 计算步骤是 -->

 

代码:

 

public class TengXunNumberPicker {

 public static void calSecondLineArray(int N){
  
  int[] firstLine = new int[N];
  int[] secondLine = new int[N];
  for(int i=0; i< N; i++){
   firstLine[i] = i;
  }
  
  System.out.print("1st Line is: ");
  print(firstLine);
  
  secondLine[1] = 2;
  secondLine[2] = 1;
  
  final int numberOfOne = 2;
  final int numberOfTwo = 1;
  final int numberOfX = 1;  // X is between N/2 to N-1
  
  int numberOfNoneZero = numberOfOne + numberOfTwo + numberOfX;
  int numberOfZero = N - numberOfNoneZero;
  
  secondLine[0] = numberOfZero;
  secondLine[numberOfZero] = 1;
  
  
  System.out.print("2nd Line is: ");
  print(secondLine);
  System.out.println();
 }
 
 
 public static void print(int[] array){


  for(int i: array){
   System.out.format("%3s", i);
  }
  System.out.println();
 }
 
 public static void main(String[] args){
  
  calSecondLineArray(10);
  
  calSecondLineArray(15);
  
  
 }
}

输出:

 

1st Line is:    0  1  2  3  4  5  6  7  8  9
2nd Line is:   6  2  1  0  0  0  1  0  0  0

 

1st Line is:     0  1  2  3  4  5  6  7  8  9 10 11 12 13 14
2nd Line is:  11  2  1  0  0  0  0  0  0  0   0   1   0   0   0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值