2016-08-29 28 views
0

正方行列の場合、各セルは黒(1)か白(0)のいずれかで、境界が黒い最大正方形を見つけることができます。私のコードはPython 2.7で、論理的に正しいのだろうか?パフォーマンスの向上ありがとう。黒い境界線を持つ最大正方形を見つけよう

私の主なアイデアは、上に(連続的に)、左に(連続的に)どれくらい多くの黒いノードがあるかを把握することです。lefttopのマトリックスが表します。次に、lefttopのトラッキングに基づいて、どのノードでも、最上部と左側の連続する黒ノードの最小値を見つけようとします。そして、最小値をベースにして正方形が形成できるかどうかを調べます。

A=[[1,1,0,0,0], 
    [1,1,1,1,1], 
    [0,0,1,0,1], 
    [0,0,1,1,1], 
    [0,0,0,0,0]] 

top=[[0] * len(A[0]) for i in range(len(A))] 
left=[[0] * len(A[0]) for i in range(len(A))] 
result = 0 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i-1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j-1] + 1 if j > 0 else 1 
print top 
print left 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i-1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j-1] + 1 if j > 0 else 1 

      x = min(top[i][j], left[i][j]) 
      if x > 1: 
       y = min(left[i-x+1][j], top[i][j-x+1]) 
       result = max(result, y) 

print result 

編集1、j_random_hackerによって指されている問題を、解決します。

A = [[1, 1, 0, 0, 0], 
    [1, 1, 1, 1, 1], 
    [0, 0, 1, 0, 1], 
    [0, 0, 1, 1, 1], 
    [0, 0, 0, 0, 0]] 

A = [[0,1,1], 
    [1,0,1], 
    [1,1,1]] 

top = [[0] * len(A[0]) for i in range(len(A))] 
left = [[0] * len(A[0]) for i in range(len(A))] 
result = 0 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i - 1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j - 1] + 1 if j > 0 else 1 
print top 
print left 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i - 1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j - 1] + 1 if j > 0 else 1 

      x = min(top[i][j], left[i][j]) 
      if x > 1: 
       y = min(left[i - x + 1][j], top[i][j - x + 1]) 
       if x == y: 
        result = max(result, y) 

print result 

編集2、j_random_hackerによって問題を解決します。

A = [[0,1,0,0], 
    [1,1,1,1], 
    [0,1,0,1], 
    [0,1,1,1]] 

A = [[0,1,1], 
    [1,0,1], 
    [1,1,1]] 

A = [[1, 1, 0, 0, 0], 
    [1, 1, 1, 1, 1], 
    [0, 0, 1, 0, 1], 
    [0, 0, 1, 1, 1], 
    [0, 0, 0, 0, 0]] 


top = [[0] * len(A[0]) for i in range(len(A))] 
left = [[0] * len(A[0]) for i in range(len(A))] 
result = 0 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i - 1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j - 1] + 1 if j > 0 else 1 
print top 
print left 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i - 1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j - 1] + 1 if j > 0 else 1 

      x = min(top[i][j], left[i][j]) 
      while x > 1: 
       y = min(left[i - x + 1][j], top[i][j - x + 1]) 
       if x == y: 
        result = max(result, y) 
        break 
       x -= 1 

print result 

編集3、新しい修正

A = [[0,1,0,0], 
    [1,1,1,1], 
    [0,1,0,1], 
    [0,1,1,1]] 

A = [[1, 1, 0, 0, 0], 
    [1, 1, 1, 1, 1], 
    [0, 0, 1, 0, 1], 
    [0, 0, 1, 1, 1], 
    [0, 0, 0, 0, 0]] 

A = [[0,1,1], 
    [1,0,1], 
    [1,1,1]] 

top = [[0] * len(A[0]) for i in range(len(A))] 
left = [[0] * len(A[0]) for i in range(len(A))] 
result = 0 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i - 1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j - 1] + 1 if j > 0 else 1 
print top 
print left 

for i in range(len(A)): 
    for j in range(len(A[0])): 
     if A[i][j] == 1: 
      top[i][j] = top[i - 1][j] + 1 if i > 0 else 1 
      left[i][j] = left[i][j - 1] + 1 if j > 0 else 1 

      x = min(top[i][j], left[i][j]) 
      while x > 1: 
       y = min(left[i - x + 1][j], top[i][j - x + 1]) 
       if x <= y: 
        result = max(result, x) 
        break 
       x -= 1 

print result 
+1

@OhadEytan Nope。ユーザーは、コードが動作することを確信しているようには見えません。また、スタック交換ネットワーク上のどこからでもコードがオフトピックであると思う場合は、そこからオフトピックであるため、コードを閉じます。他の場所で話題になっているかもしれないし、そうでないかもしれないからでもない。コードレビューが移行の対象としてリストされていないのが良い理由です。 – Mast

+1

@Mast私は、OPが[質問](「http://codereview.stackexchange.com/help/on-topic」)に「はい」と答えていると思う_私の知る限りでは、コードは意図したとおりに動作しますか? "_ また、"良い理由 "_とそのコメントの[こちら](http://meta.stackoverflow.com/a/251654/2069380)をご覧ください。 –

+1

@OhadEytan私は[this](http://meta.stackoverflow.com/a/311349/1014587)とリンクしています。OPがはいと答えるかどうかについては、OPはそれが機能するかどうかを明らかにする必要があります。 'Python 2.7のコードは、論理的に正しいのだろうか?と思っていますが、彼が出力を確認したかどうか疑問に思います。 – Mast

答えて

1

次のような単純な反例を示し、これは、論理的に正しくない:

011 
101 
111 

この配列には何のボーダーの正方形が含まれていませんが、あなたのコードでは、辺の長さ3の正方形が含まれていることが報告されています。を介して3番目のネストループが必要です。から1(解決策O(n^3) - 時間を作る)または場合によっては同等のチェックをより迅速に実行することができるより洗練されたデータ構造を有する0候補正方形サイズ。

[更新アルゴリズムに対処するEDIT]

新しいアルゴリズムは、3×3の一方がそれぞれに存在しているにもかかわらず

0100 
1111  1111 
0101 or 0101 
0111  0111 

いずれかにはボーダー正方形が存在しないと考えています。

修正を推測しなくても、すべての可能なの枠内の四角形の位置を効率的(または効率的でないこともあります)に分解することを検討してください。私が上に向かって言いましたように、境界がついた四角形の可能な右下隅について、あなたのコードは現在のところ、という1つのの長方形だけをチェックしています。しかし、より多くの四角形が(i、j)を右下隅に持つことができます - それらのテストはどこですか?

+0

問題を指摘してくれたj_random_hackerに感謝します。私のロジックに何が間違っているのでしょうか?私は自分のコードが右下から左下、右上、そして最後に左上にチェックしていると思った。 –

+0

私のコードで問題を修正しました。編集1部を参照してください。別のループなしでO(n^2)時間で実行可能です。事前のアドバイスをいただきありがとうございます。 –

+0

ありがとうj_random_hacker、あなたの入力のために、私のコード出力0、私はそれが正しい値だと思います。あなたは1を出力すべきだと思いますか?左のサンプルは正方形でなければならないのでテストします。 –

関連する問題