【问题描述】 面试题62. 圆圈中最后剩下的数字
0,1,,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字。求出这个圆圈里剩下的最后一个数字。例如,0、1、2、3、4这5个数字组成一个圆圈,从数字0开始每次删除第3个数字,则删除的前4个数字依次是2、0、4、1,因此最后剩下的数字是3。示例 1:输入: n = 5, m = 3
输出: 3
示例 2:输入: n = 10, m = 17
输出: 2
【解答思路】
1. 暴力法
- 元素插进列表
- 每次移动m-1,删除所在元素,list长度n-1
时间复杂度:O(N^2) 空间复杂度:O(N)
public int lastRemaining(int n, int m) {ArrayList<Integer> list = new ArrayList<>(n);for (int i = 0; i < n; i++) {list.add(i);}int idx = 0;while (n > 1) {idx = (idx + m - 1) % n;list.remove(idx);n--;}return list.get(0);}作者:sweetieeyi
链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/javajie-jue-yue-se-fu-huan-wen-ti-gao-su-ni-wei-sh/
2. 数学方法
-约瑟夫环
-倒推
时间复杂度O(N)
class Solution {public int lastRemaining(int n, int m) {int ans = 0;// 最后一轮剩下2个人,所以从2开始反推for (int i = 2; i <= n; i++) {ans = (ans + m) % i;}return ans;}
}作者:sweetieeyi
链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/javajie-jue-yue-se-fu-huan-wen-ti-gao-su-ni-wei-sh/
【总结】
- LinkedList vs ArrayList
LinkedList 时间复杂度 O(nm) 删除指定节点 O(n) (从头到尾遍历) 大量非连续性地址访问 ->超时
ArrayList 时间复杂度 O(n^2) 删除指定元素 O(n) (需要移动) 内存连续空间的拷贝-> 勉强合格
- 数学公式无需记住 关键是掌握推导过程
链接:https://leetcode-cn.com/problems/yuan-quan-zhong-zui-hou-sheng-xia-de-shu-zi-lcof/solution/javajie-jue-yue-se-fu-huan-wen-ti-gao-su-ni-wei-sh/