問題: 11. 最も多くの水を入れる容器
記事ディレクトリ
一連の考え
最初は暴力についてしか考えていませんでしたが、そのアイデアは、既存の文字列の中で最長の回文を作成し、文字列の開始マークと終了マークを見つけるというアイデアに似ていました。
しかし提出してみたらタイムアウトになってしまったのですが、主な原因は制約条件が書きにくいのでダブルポインタを考慮して最適化する必要があることです。
問題解決法
各状態において、ロングボードとショートボードのどちらが中央まで狭くなろうとも、タンクの下端の幅 −1-1-1 が短くなります。ショートボードが内側に移動すると
、タンクのショートボード min(h[ i],h[j])min(h[i], h[j])min(h[i],h[j]) が大きくなる可能性があるため、次のシンクが増える可能性があります。
ロングボードが内側に移動すると、タンクのショートボード min(h[i],h[j])min(h[i], h[j])min(h[i],h[j])変わらない、もしくは小さくなるので、次のシンクの面積も小さくなるはずです。
そこで、水槽の左右端を揃えるように2つのポインタを初期化し、1サイクルごとにショートボードを1フレームずつ内側に移動させ、2つのポインタが出会って飛び出すまで最大面積を更新することで、最大面積を得ることができます。
複雑さ
- 時間計算量:
時間計算量を追加します。例: O ( N ) O(N)O ( N )
- 空間の複雑さ:
空間の複雑さを追加します。例: O ( 1 ) O(1)○ (1)
コード
class Solution:
def maxArea(self, height: List[int]) -> int:
start = 0
end = len(height) - 1
res = 0
while start < end:
if height[start] < height[end]:
res = max(res,height[start] * (end-start))
start = start + 1
else:
res = max(res,height[end] * (end-start))
end = end - 1
return res
ただし、最初は文字列内の最長の回文という考えで送信が行われ、タイムアウトが常に報告されていましたが、実装は難しくありません。
コード (最適化なし)
class Solution:
def maxArea(self, height: List[int]) -> int:
max_vol = 0
flag_start = 0
start_index = 0
while start_index < len(height):
if height[start_index] < height[flag_start]:
pass
else:
for i in range(start_index+1,len(height))[::-1]:
wid_ = i - start_index
hei_ = min(height[i],height[start_index])
vol = wid_ * hei_
if vol > max_vol:
max_vol = vol
flag_start = start_index
start_index = start_index + 1
return max_vol