問題描述:0,1,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈裏刪除第m個數字。求出這個圓圈裏剩下的最後一個數字。
這是力扣上的一道題。我的思路:
①首先想到的是用循環鏈表,每次從鏈表刪除一個結點,但是鏈表的讀取速度很慢,每次訪問往後的第m個結點也是很費時的。
②然後想到用數組,數組讀取速度快,但刪除一個元素後,移動剩下元素也要耗費大量時間。
③那有沒有用數組但又不刪除元素的方法呢。每刪除一個數,就把這個元素值置爲-1,每經過m個不爲-1的數,就把這個數值置爲-1,直到數組中只剩下一個不爲-1的元素,這個元素值就是答案。
④第③種方法雖然有數組的隨機訪問速度,也不用刪除元素,但數據量大的時候,運行到後面數組內有大量值爲-1的元素,要進行多次循環判斷,速度也很慢,提交後直接超時。官方給出的是數學方法,找出問題的遞歸公式,幾行代碼解決。哭唧唧,菜雞真的菜。
記錄一下第③種方法:
class Solution {
public:
int lastRemaining(int n, int m) {
vector<int> sq(n);
int i=0;
for (auto &it : sq) {
it = i;
++i;
}
int num = n; // 記錄數組內剩餘的不爲-1的元素個數
int index = 0;
while (num>1) {
int j = 0;
while (j ==0 || j != m) {
if (sq[index % n] != -1) {
++j;
}
++index;
}
sq[(index-1)%n] = -1; // 將第m個不爲-1的元素值置爲-1
--num;
}
for (auto it : sq) {
if (it != -1) {
i = it;
break;
}
}
return i;
}
};