剑指Offer:圆圈中最后剩下的数字
2018-03-18 13:10
225 查看
0,1,……,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字。求出这个圆圈最后剩下的那个数字。
这是著名的约瑟夫环问题,下面提供两种解法。
实现代码:
经过复杂的推导(省略)我们可以得到以下递归式:
使用循环实现代码:
这种方法实现代码真的是太简洁了,Offer稳了!
这是著名的约瑟夫环问题,下面提供两种解法。
经典解法:使用环形链表
自己创建一个环形链表比较麻烦,这里我使用LinkedList来模拟环形链表。但是LinkedList不是环形的,所有每当迭代器(iterator)扫描到链表尾部时要将它移到头部,从而实现环形。实现代码:
private static int LastNumOfRing(int n,int m){ if(n<0|m<1){ return -1; } List<Integer> list = new LinkedList<Integer>(); //由于JAVA中对集合进行遍历时不能修改集合,所有我将要删除的元素暂时放在temp中,待遍历完再删除list中的元素 List<Integer> temp = new ArrayList<Integer>(); for(int i=0;i<n;i++){ list.add(i); } int count=1; Iterator<Integer> iterator = list.iterator(); int size=list.size(); while(size>1){ if(iterator.hasNext()){ }else{ iterator = list.iterator();//回到开头 } Integer num = iterator.next(); if(temp.contains(num)){ continue; } if(count==m){ temp.add(num); count=1; size--; list.toString(); }else{ count++; } } for (Integer integer : temp) { list.remove(integer); } return list.get(0); }
创新解法:找规律
首先我们定义一个函数f(n,m)表示每次在0~n-1中每次删除第m个数字最后剩下的那个数字。经过复杂的推导(省略)我们可以得到以下递归式:
使用循环实现代码:
private static int LastNumOfRing(int n,int m){ if(n<0|m<1){ return -1; } int last=0; for(int i=2;i<=n;i++){ last = (last+m)%i; } return last; }
这种方法实现代码真的是太简洁了,Offer稳了!
相关文章推荐
- <未完成状态>剑指offer_圆圈中最后剩下的数字(约瑟夫问题)
- 剑指offer之面试题45圆圈中最后剩下的数字
- 【剑指Offer学习】【面试题45:圆圈中最后剩下的数字(约瑟夫环问题)】
- 剑指Offer 面试题45:圆圈中最后剩下的数字(约瑟夫环问题,ZOJ 1088:System Overload类似)题解
- 【剑指offer】6.4抽象建模能力——面试题45:圆圈中最后剩下的数字
- 剑指offer 6.4 抽象建模能力3 -圆圈中最后剩下的数字
- 【剑指offer】题45:圆圈中最后剩下的数字
- [剑指offer] 圆圈中最后剩下的数字
- 剑指offer——面试题47:圆圈中最后剩下的数字
- 剑指Offer——圆圈中最后剩下的数字
- 剑指Offer:面试题45 圆圈中最后剩下的数字
- 剑指Offer 45圆圈中最后剩下的数字
- 剑指 offer set 21 圆圈中最后剩下的数字
- 剑指Offer面试题45圆圈中最后剩下的数字(约瑟夫环问题),面试题46求1+2+...+n
- 剑指Offer面试题45:圆圈中最后剩下的数字
- 剑指offer-面试题45-圆圈中最后剩下的数字
- 剑指offer面试题目:圆圈中最后剩下的数字(约瑟夫环)
- 【剑指Offer】面试题45:圆圈中最后剩下的数字
- 剑指offer 45. 圆圈中最后剩下的数字
- 【剑指Offer-抽象思维能力】圆圈中最后剩下的数字