网易2016笔试(2)

有n个信封,包含n封信,现在把信拿出来,再装回去,要求每封信不能装回它原来的信封,问有多少种装法?

给定一个整数n,请返回装发个数,为了防止溢出,请返回结果Mod 1000000007的值。保证n的大小小于等于300。

测试样例:2   返回 1

一开始我以为是卡特兰数问题:卡特兰数应用

考虑半天,但是也无法列出卡特兰数的公式。安静下来发现,h(0)=h(1)=0,不满足卡特兰数条件。于是乎就想请教大神。大神给了个思路:

计算f(n),假设1,2,3,4,......n。那么n若放在位置i,可以分两种情况考虑。i放在位置n和i不放在位置n。为什么这么考虑呢?因为如果i放在n,那么剩下就是f(n-2),否则的话就是f(n-1)。第一种情况你很容易理解,i和n都放好了,剩下的就是n-2个数不放在原来的信封里。但是i如果不放在n位置,剩下n-1个数,其中i放哪都可以啊,和题目中每个信封不放在原信封条件不同啊。很好,i是可以放在任何位置,但前提假设了这种情况是i不放在n位置。这样这n-1个数,除了i,其余的限制是不放在原信封,i的限制是不放在n位置。所以等价这其实就是f(n-1)。

问题到这,用递归计算就太简单了。代码如下:

int countWays(int n) {
        // write code here
        if(n<2)return 0;
        if(n==2)return 1;
        return (n-1)*(countWays(n-1)%1000000007+countWays(n-2)%1000000007);
    }

问题求得的结果没得问题,但是时间使用超过3000ms,远远超过限制时间。

但也可以猜想到,就是上述代码重复计算了太多值。于是乎,就改用循环。代码如下:

int countWays(int n) {
        // write code here
       int a=0;
       int b=1;
        if(n<=1)return a;
        if(n==2)return b;
        long result;
        long x=0;
        long y=1;
        for(int i=3;i<=n;i++)
            {
            result=(i-1)*(x+y)%1000000007;
            x=y;
            y=result;
        }
        return result;
    }

这样就很好了,根据n的大小,从头到尾计算一遍,直至f(n)。

总结:在一个序列上递归就很容易产生重复计算的问题,造成代码效率不高。同时一开始考虑问题总想着套路,这样并不好。有思路有解法才能利用公式等工具解决问题。先想解法,再看是不是公式,再解题。

时间: 2024-10-13 12:07:07

网易2016笔试(2)的相关文章

网易2016笔试(3)

有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数. 给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在. 测试样例:[1,3,5,2,2],5,3 返回:2 我的第一个思路,使用快排进行排序,排序后就可以得到第k个最大的数了. int quicksort(vector<int>&a,int i,int j) { int k=a[i]; while(i<j) { while(j>i&&a[j]>

网易2016笔试(1)

小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量.这些钻石的重量各不相同.在他们们比较了一段时间后,它们看中了两颗钻石g1和g2.现在请你根据之前比较的信息判断这两颗钻石的哪颗更重. 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号.最后给定之前的比较次数n.请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0.输入数据保证合法,不会有矛盾情况

&lt;转&gt;网易2016实习生前端笔试题部分总结

网易2016实习生前端笔试题部分总结 原文地址:http://www.cnblogs.com/venoral/p/5325202.html 这只是部分题,答案为个人观点如有错误欢迎指出,感觉考点都挺基础,但是很注重考细节方面,通过整理也知道自己在CSS3和HTML5,网络知识等方面的不足还是得多学多练多思考.攒rp,希望自己在明天360笔试中能轻松答过~ css 1.多选 //HTML <p>很长的一段文字,很长的一段文字,很长的一段文字,特别长的文字</p> //CSS p{ w

2016年网易在线笔试

网易技术类笔试

网易 1.对于一个内存地址是32位.内存页是8KB的系统.0X0005F123这个地址的页号与页内偏移分别是多少. 2.如果X大于0并小于65536,用移位法计算X乘以255的值为: 3.一个包含n个节点的四叉树,每个节点都有四个指向孩子节点的指针,这4n个指针中有多少个空指针? 5.计算机在内存中存储数据时使用了大.小端模式,请分别写出A=0X123456在不同情况下的首字节是,大端模式:0X12   小端模式:0X56 X86结构的计算机使用  小端    模式.一般来说,大部分用户的操作系

网易 2016 实习研发工程师 3道 编程题-2

有一棵二叉树,树上每个点标有权值,权值各不相同,请设计一个算法算出权值最大的叶节点到权值最小的叶节点的距离.二叉树每条边的距离为1,一个节点经过多少条边到达另一个节点为这两个节点之间的距离. 给定二叉树的根节点root,请返回所求距离. //import java.util.ArrayList;   //import java.util.HashMap;   //import java.util.Iterator;   //import java.util.LinkedList;   //imp

网易 2016 实习研发工程师 3道 编程题-1

小明陪小红去看钻石,他们从一堆钻石中随机抽取两颗并比较她们的重量.这些钻石的重量各不相同.在他们们比较了一段时间后,它们看中了两颗钻石g1和g2.现在请你根据之前比较的信息判断这两颗钻石的哪颗更重. 给定两颗钻石的编号g1,g2,编号从1开始,同时给定关系数组vector,其中元素为一些二元组,第一个元素为一次比较中较重的钻石的编号,第二个元素为较轻的钻石的编号.最后给定之前的比较次数n.请返回这两颗钻石的关系,若g1更重返回1,g2更重返回-1,无法判断返回0.输入数据保证合法,不会有矛盾情况

网易2016研发工程师编程题:路灯

路灯 一条长l的笔直的街道上有n个路灯,若这条街的起点为0,终点为l,第i个路灯坐标为ai,每盏灯可以覆盖到的最远距离为d,为了照明需求,所有灯的灯光必须覆盖整条街,但是为了省电,要是这个d最小,请找到这个最小的d. 输入描述: 每组数据第一行两个整数n和l(n大于0小于等于1000,l小于等于1000000000大于0).第二行有n个整数(均大于等于0小于等于l),为每盏灯的坐标,多个路灯可以在同一点. 输出描述: 输出答案,保留两位小数. 输入例子: 7 1515 5 3 7 9 14 0

网易多线程笔试题目学习

题目:一个线程打印 1~52,另一个线程打印字母A-Z.打印顺序为12A34B56C……5152Z. package my.thread.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import