腾讯面试题:
给你10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每个数都是先前上排那十个数在下排出现的次数。
上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】
举一个例子,
数值: 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 次....
给你10 分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每个数都是先前上排那十个数在下排出现的次数。
上排的十个数如下:
【0,1,2,3,4,5,6,7,8,9】
举一个例子,
数值: 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 次....
以此类推..
思路:如果采用暴力穷举法的话,时间效率不好。仔细观察不难得知,下排数字总和加起来为10,可以利用这个性质,通过递归,得到下排可能的排列结果,然后再判断这些结果是否满足下排个数是上排对应位置数字的出现频率,得出最终结果。
代码:
namespace MS100P_6
{
const int Len = 10;
bool isLegal(int *A, int n)
{
int count = 0;
for (int i = 0; i < n; i++)
{
int frequency = 0;
for (int j = 0; j < n; j++)
{
if (i == A[j])
frequency++;
}
if (A[i] != frequency)
return false;
}
return true;
}
void genArray(int *A, int n, int Sum)
{
if (n < 1) return;
if (n == 1)
{
A[0] = Sum;
if (isLegal(A, Len))
{
for (int i = 0; i < Len; i++)
cout << A[i] << ' ';
cout << endl;
}
}
else
for (int i = 0; i<Sum; ++i)
{
A[n - 1] = i;
genArray(A, n - 1, Sum - i);
}
}
void test()
{
int A[Len];
for (int i = 0; i < Len; i++)
cout << i << ' ';
cout << endl;
genArray(A, Len, Len);
}
}