百人開燈問題解法及優化
一:題意
房間裡有100盞電燈,編號為1,2,3……100,每盞燈上有一個按鈕,初始時燈全都是關的。編好號的100位同學由房間外依次走進去,將自己編號的倍數的燈的按鈕全部按一次
- 第一位同學把編號是1的倍數的燈的按鈕按一下(此時100盞燈全亮)
- 第二位同學把編號是2的倍數的燈的按鈕按一下(此時只有50盞燈亮著,50盞被這個人按滅了
- ……
- 第100位同學把編號是100的倍數的燈(即編號為100的燈)的按鈕按一下
請問依次走完後,還有多少盞燈亮著?
二:實現
1:暴力法
-
雙迴圈暴力破解
-
時間複雜度:O(n*n)
-
空間複雜度:O(1)
-
程式碼實現:
/**
* 暴力法
* 時間複雜度:O(n*n)
*/
public class Test {
public static void main(String[] args) {
int[] light = new int[101];
//初始化為燈關閉
for (int i = 1; i < light.length; i++) {
light[i] = 0;
}
//關燈操作
for (int i = 1; i < light.length; i++) {
for (int j = 1; j < light.length; j++) {
if(j%i == 0) {
light[j] = light[j] == 0 ? 1 : 0;
}
}
}
//輸出開啟的燈
for (int i = 1; i < light.length; i++) {
if(light[i] == 1)
System.out.println(i);
}
/**
* 輸出
* 1
* 4
* 9
* 16
* 25
* 36
* 49
* 64
* 81
* 100
*/
}
}
2:優化一:
-
觀察發現每一盞燈都只會被比自身小並且是自身約數的值和自身 進行開啟或者關閉操作
-
我們將自身數對燈的開啟關閉排除,則比這盞燈小並且是這盞燈約數的值為偶數,則最後為開燈,否則最後為熄燈
-
時間複雜度會比單純的暴力法降低一些
-
程式碼如下:
/**
* 優化暴力法
* 時間複雜度:O(n*n),但會比單純的暴力法時間複雜度低
*/
public class Test {
public static void main(String[] args) {
int[] light = new int[101];
//初始化為燈關閉
for (int i = 1; i < light.length; i++) {
light[i] = 0;
}
//關燈操作
for (int i = 1; i < light.length; i++) {
for (int j = 1; j < i; j++) {
if(i%j == 0) {
light[i]++;
}
}
}
//輸出開啟的燈
for (int i = 1; i < light.length; i++) {
if(light[i]%2 == 0)
System.out.println(i);
}
/**
* 輸出
* 1
* 4
* 9
* 16
* 25
* 36
* 49
* 64
* 81
* 100
*/
}
}
3:優化二:
-
觀察發現,每盞燈都會被“1”操作一次,也會被自身的值操作一次,這兩次相互抵消
-
對於燈i,如果存在一個i的約數j,那麼一定存在另外一個約數k,如果j != k ,那麼這兩次相互抵消,如果j == k,那麼只有一個這樣的值,不會被抵消,這樣只有存在完全約數(比如:4 = 2*2 , 9 = 3*3類的)的燈才不會被抵消,所以我們要求的就是具有完全約數的值。
-
所以我們只要判斷值的開方是不是整數就可以了
-
時間複雜度:O(n)
-
沒有通用性,程式碼如下:
/**
* 具體問題具體分析,沒有通用性
* 時間複雜度:O(n)
*/
public class Test {
public static void main(String[] args) {
int[] light = new int[101];
//初始化為燈關閉
for (int i = 1; i < light.length; i++) {
light[i] = 0;
}
//關燈操作並輸出
for (int i = 1; i < light.length; i++) {
double k = Math.sqrt(i);
int m = (int)k;
if((double)m == k) {
System.out.println(i);
}
}
/**
* 輸出
* 1
* 4
* 9
* 16
* 25
* 36
* 49
* 64
* 81
* 100
*/
}
}
相關文章
- MySQL資料庫開發常見問題及優化MySql資料庫優化
- topK問題解法TopK
- 運籌優化(六)--目標規劃定義及解法優化
- MySQL資料庫開發常見問題及幾點優化!MySql資料庫優化
- 演算法篇-開燈問題演算法
- 大資料下的統計學:問題優先而非解法優先大資料
- 凸優化問題優化
- 效能優化問題優化
- 【調優】設計問題還是優化問題?優化
- 八皇后問題python解法Python
- RMQ問題的各種解法MQ
- SpringCloud之Eureka的常見問題及配置優化SpringGCCloud優化
- Oracle rownum 分頁引起的效率問題及優化思路Oracle優化
- 斜率優化(凸包優化)DP問題acm優化ACM
- 10元買啤酒問題Java解法Java
- JavaScript的two-sum問題解法JavaScript
- 幾數之和分析,解法,優化和總結優化
- 移動端網路常見問題及優化對策優化
- 移動 Web 開發問題和優化小結Web優化
- 03-凸優化問題優化
- 數值最優化—優化問題的解(二)優化
- 大資料風控的現狀、問題及優化路徑大資料優化
- 做百度優化常見的十個問題及解答優化
- 多路口交通燈問題
- iOS開發那些事-效能優化–autorelease的使用問題iOS優化
- 【離散優化】覆蓋問題優化
- 記一個效能優化問題優化
- go的編譯優化問題Go編譯優化
- N皇后問題(各種優化)優化
- SQL優化--not in和or出的問題SQL優化
- SQL優化引出的問題(二)SQL優化
- SQL優化引出的問題(一)SQL優化
- 四人過橋問題的SQL解法SQL
- TensorFlow系列專題(九):常用RNN網路結構及依賴優化問題RNN優化
- 如何解決百人研發團隊的管理問題?
- 決策樹減支問題(優化)dfs減支問題優化
- webpack dll打包重複問題優化Web優化
- iOS問題整理08----效能優化iOS優化