欢迎转载,转载请务必注明出处:http://blog.csdn.net/alading2009/article/details/45340319
GitHub地址:https://github.com/frank-cq/MyTest
第18题(数组):n个数字(0,1,…,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。
看到该题,第一个想到的是使用循环链表模拟删除数字的过程,但是题目规定使用数组,于是。。。看了答案,此题类似约瑟夫问题,而约瑟夫问题在《具体数学》第一章中有讲解。,这是WiKi上的约瑟夫问题解释。July大神的答案解法基于递推公式:
f(n,m)=[f(n−1,m)+m]%n ,使用循环求解结果(如果使用递归会更容易与公式联系起来)。
代码
package test018;
/**
* Created by cq on 2015/4/27.
* 第18题:n个数字(0,1,...,n-1)形成一个圆圈,从数字0开始,每次从这个圆圈中删除第m个数字
* (第一个为当前数字本身,第二个为当前数字的下一个数字)。当一个数字删除后,
* 从被删除数字的下一个继续删除第m个数字。求出在这个圆圈中剩下的最后一个数字。
*/
public class Test018 {
public static int deleteMthNum(int[] arr, int m){
if (arr == null){
return -1;
}
int fnIndex = 0;
for (int i = 2; i <= arr.length; i++){
fnIndex = (fnIndex+m)%i;
}
return arr[fnIndex];
}
public static void main(String[] args){
int[] arr = {1,2,3,4,5,6,7};
System.out.println(deleteMthNum(arr,2));
System.out.println(deleteMthNum(arr,3));
System.out.println(deleteMthNum(arr,4));
}
}
执行结果
Connected to the target VM, address: '127.0.0.1:13865', transport: 'socket'
7
4
2
Disconnected from the target VM, address: '127.0.0.1:13865', transport: 'socket'
Process finished with exit code 0
数学解题确实相当的优雅,后面有时间再好好看看《具体数学》上的约瑟夫问题。