45、圓圈中最後剩下的數字
阿新 • • 發佈:2017-07-01
pen 重復 color list 操作 port cnblogs int span
思路1:環形鏈表,每次只刪除一個數,都從第0個開始。每次都從鏈表重復遍歷,每刪除一個,走m步,共n遍
時間O(nm),空間o(n)
import java.util.*; public class Solution { public int LastRemaining_Solution(int n, int m) { if(n < 1 || m < 1) { return -1; } List<Integer> list = new LinkedList<>();View Codefor (int i = 0; i < n; i++) { list.add(i); } int idx = 0; while(list.size() > 1) { // 只要移動m-1次就可以移動到下一個要刪除的元素上 for (int i = 1; i < m; i++) { idx = (idx + 1) % list.size();//保證刪除後,當數組數量小於m時,仍能正確的去刪除 } list.remove(idx); }return list.get(0); } }
思路2:時間O(n),空間o(1),
f(n,m) = f ‘(n - 1, m) {刪除一個數後,再每次去刪除第m個,最後剩下的數 ,一定等於, 上一次操作中,再每次去刪除第m個,最後剩下的數}
即,不管處於第幾次刪除第m個數的循環裏,最後剩下的數是一樣的。
f(n,m) = {0,n=1(f(n,m)表示在n個數中,每次刪除第m個後,最後剩下的一個數)
[f(n -1,m) + m] % n, n > 1
public class Solution { publicView Codeint LastRemaining_Solution(int n, int m) { if (n < 1 || m < 1) { return -1; } int last = 0; for (int i = 2; i <= n; i++) { last = (last + m) % i; } return last; } }
45、圓圈中最後剩下的數字