【問題】
首先,讓小朋友們圍成乙個大圈。然後,隨機指定乙個數 m, 讓編號為 0 的小朋友開始報數。每次喊到 m-1 的那個小朋友要出列唱首歌,並且不再回到圈中,從他的下乙個小朋友開始,繼續 0…m-1 報數… 這樣下去… 直到剩下最後乙個小朋友,哪個小朋友會在最後表演呢?(注:小朋友的編號是從 0 到 n-1)
如果沒有小朋友,請返回 - 1
【題解
一、陣列模擬環】
public
intsolution1
(int n,
int m)
int k,index,count;
boolean
flag =
newboolean
[n];
k =0;
// 記錄迴圈次數
index =0;
// 游標,記錄陣列下標
count =0;
// 記錄跳出個數
while
(count < n-1)
k++;}
index ++;if
(index == n)
} k =0;
} index =0;
while
(index < n)
return index;
}
ps:可以用list(arraylist或者linkedlist來代替普通陣列、這類動態陣列在該類問題上可以提公升效率)
【題解
二、鍊錶模擬】
class
listnode
}public
class
solution
listnode head =
newlistnode(0
);listnode node = head;
for(
int i =
1; i < n; i++
) node.next = head;
int k =0;
while
(node.next != node)
else
}return node.val;
}// 鍊錶解法二
public
intsolution3
(int n,
int m)
p.next = head;
// 構成閉環
k =0;
p = head;
// 當只有乙個節點的時候跳出
while
(p.next != p)
k =0;
// m-1的節點跳出
p.next = p.next.next;
// 把游標p點位到m位置
p = p.next;
}return p.val;
}}
【題解
三、數學算式】
f(n,m) = ( f(n−1,m) + m ) % n
// 非遞迴
public
intsolution4
(int n,
int m)
int num =0;
for(
int i =
2; i <= n; i++
)return num;
}// 遞迴演算法
public
intsolution5
(int n,
int m)
if(n ==1)
return0;
return
(solution5
(n-1
,m)+ m)
% n;
}
約瑟夫環問題 多解
這裡引入乙個之前做過的一道題目 7 28 猴子選大王 20分 一群猴子要選新猴王。新猴王的選擇方法是 讓n只候選猴子圍成一圈,從某位置起順序編號為1 n號。從第1號開始報數,每輪從1報到3,凡報到3的猴子即退出圈子,接著又從緊鄰的下乙隻猴子開始同樣的報數。如此不斷迴圈,最後剩下的乙隻猴子就選為猴王。...
約瑟夫環問題數學解法
首先一開始的序列 序列1 1,2,3,4,n 2,n 1,n 此時出佇列的第乙個人,位置為k,號碼肯定是m n。這個應該沒有問題,也就是取餘操作使得陣列類似能夠有迴圈的功能。此時序列2 1,2,3,4,k 1,k 1,n 2,n 1,n 此時k出佇列,序列2中為n 1個人了。根據序列2,得到序列3 ...
約瑟夫環O N 解法
無論是用鍊錶實現還是用陣列實現都有乙個共同點 要模擬整個遊戲過程,不僅程式寫起來比較煩,而且時間複雜度高達o nm 當n,m非常大 例如上百萬,上千萬 的時候,幾乎是沒有辦法在短時間內出結果的。我們注意到原問題僅僅是要求出最後的勝利者的序號,而不是要讀者模擬整個過程。因此如果要追求效率,就要打破常規...