2017-06-06 10 views
-1

leetcode から取られた古典的な数学のブレーンツェーサー問題文 "最初にすべての電球が点灯しています。すべての2番目の電球をオフにします。3番目のラウンドでは、3番目の電球をトグルします(オンの場合はオン、オフの場合はオフにします)。最後の球。nラウンド後にどのくらいの球根があるか調べる。Pythonの範囲関数ステップサイズリストの割り当て範囲外のエラー、ブレーンジサーをシミュレートする

私は問題自体に簡潔な解決策があることを認識していますが、電球のオン/オフ切り替えの問題をシミュレートしたいと思います。しかし、ステップサイズが増えるにつれて、範囲外のエラーのリストインデックスを実行していますが、どうすればこのエラーを処理できますか?インデックスが有効な場合にのみ、値を切り替える必要があります。

def bulbSwitch(self, n): 
     """ 
     :type n: int 
     :rtype: int 
     """ 
     bulbs= [0]*n 
     step=0 
     for i in range(n): 
      step += 1 
      for s in range(0, n, step): 
       bulbs[s+i]=0 if bulbs[s]==1 else 1 #this line produces error 
     print bulbs 
+1

をなぜ '電球[s + i]'ですか? – jonrsharpe

+0

@jonrsharpe私は電球[0]から始めるのは嫌いです。ステップサイズが2のときは、電球[1]で始まり、ステップサイズは3、電球[2]などで始まります。 – codeAligned

+0

それを得るが、なぜ現在のラウンドの番号を追加するのですか? – jonrsharpe

答えて

3

他の人も指摘しているように、問題はs+iです。ループ内のsの最大値はn-1です。何も追加しない場合は、リストの最後を過ぎて実行します。

あなたはとてもだけではなく、そこにあなたの範囲を開始するなど、あなたがstepが2の場合stepが3であるとき、bulbs[1]bulbs[2]を開始したいと述べた。

for step in range(1, n+1): # this avoids separate `i` vs. `step` variables 
    for s in range(step-1, n, step): # start in the right place 
     bulbs[s] = 0 if bulbs[s] == 1 else 1 

EDIT

おそらく、これがありますより簡単に? (ここで私が代わりに-1+1を使用していました。)

for step in range(n): # this avoids separate `i` vs. `step` variables 
    for s in range(step, n, step+1): # start in the right place 
     bulbs[s] = 0 if bulbs[s] == 1 else 1 

EDIT 2

はちょうど私がテスト(通過する)を追加...それが動作を確認すること:

import math 

def bulb_switch(n): 
    bulbs = [0] * n 

    for step in range(n): # this avoids separate `i` vs. `step` variables 
     for s in range(step, n, step+1): # start in the right place 
      bulbs[s] = 0 if bulbs[s] == 1 else 1 

    return sum(bulbs) 

for i in range(1000): 
    assert math.floor(math.sqrt(i)) == bulb_switch(i) 
+0

それがうまく機能し、私は今、より適切に範囲を()を使用する方法を学びました。このコードは、電球の正しい配列を返しますが、nが大きい場合(9999)、leetcode OJによって遅すぎるとみなされます。 – codeAligned

+0

FWIW、これを 'bulbs [s]^= 1'で最適化しようとしましたが、少し遅くなってしまいました(ただし、ちょうど適切な' timeit'テストではなくbash timeコマンドでテストしました)。私は 'if'テストを推測し、リスト項目を定数に設定するのは算術演算よりも高速です。しかたがない。 :) –

+0

@ user53008私は、テストに合格するためには、あなたが数学的な解を書く必要があることを確かめるために、大量の値を渡すと仮定します( 'n'が増えるにつれて遅くなりません)。 – smarx

関連する問題