Siri Bercakap dengan Anda #2

王林
Lepaskan: 2024-07-21 19:43:52
asal
496 orang telah melayarinya

Pengenalan

Hari ini kami akan memulakan gambaran keseluruhan kami tentang konsep yang digunakan untuk menangani pelbagai masalah algoritma. Pemahaman tentang konsep tertentu mungkin memberi anda intuisi dari sudut mana untuk mula memikirkan penyelesaian yang berpotensi.

Terdapat konsep yang berbeza tetapi tidak terlalu banyak di luar sana. Hari ini saya akan melaburkan perhatian anda ke dalam konsep tingkap gelongsor.

Tingkap Gelongsor

Talk with You Series #2

Konsep tingkap gelongsor sedikit lebih terlibat, berbanding pada pandangan pertama. Saya akan menunjukkannya dalam contoh praktikal. Buat masa ini, perlu diingat, idea konsep ialah kita akan mempunyai beberapa tetingkap yang perlu kita alihkan. Mari kita mulakan dari contoh segera.

Andaikan anda mempunyai tatasusunan integer dan saiz subarray yang dipratakrifkan. Anda diminta mencari subarray (aka tetingkap) sedemikian yang mana jumlah nilainya akan menjadi maksimum antara lain.

array = [1, 2, 3] window_size = 2 # conceptually subarray_1 = [1, 2] --> sum 3 subarray_2 = [2, 3] --> sum 5 maximum_sum = 5
Salin selepas log masuk

Nah, kelihatan agak mudah:
(1) tingkap gelongsor saiz 2
(2) 2 subarray
(3) kira jumlah setiap
(4) cari maks antara mereka

Mari kita laksanakan.

def foo(array: List[int], size: int) -> int: maximum = float("-inf") for idx in range(size, len(array)+1): left, right = idx-size, idx window = array[left:right] maximum = max(maximum, sum(window)) return maximum
Salin selepas log masuk

Nampaknya kami baru sahaja menggunakan konsep tingkap gelongsor dengan cekap. Sebenarnya, tidak betul-betul. Kita mungkin mendapat "bukti" itu dengan memahami kerumitan masa penyelesaian.

Kerumitannya ialah O(l)*O(w), dengan l ialah jumlah tetingkap dalam tatasusunan dan w ialah jumlah elemen dalam tetingkap. Dalam erti kata lain, kita perlu merentasi l tingkap dan untuk setiap tetingkap l-th kita perlu mengira jumlah elemen w.

Apa yang dipersoalkan di sini? Mari kita gambarkan secara konseptual lelaran untuk menjawab soalan.

array = [1, 2, 3, 4] window_size = 3 iterations 1 2 3 4 5 |___| |___| |___|
Salin selepas log masuk

Jawapannya ialah walaupun kita meluncurkan tatasusunan, pada setiap lelaran kita perlu "mengira semula" elemen k-1 yang telah dikira pada lelaran sebelumnya.

Pada asasnya, pandangan ini sepatutnya mencadangkan kita untuk bertanya soalan:

"adakah cara untuk memanfaatkan pengiraan daripada langkah sebelumnya?"

Jawapannya ya. Kita boleh mendapatkan jumlah elemen tetingkap dengan menambah dan menolak yang pertama dan seterusnya selepas elemen tetingkap. Biar saya masukkan idea ini ke dalam kod.

def foo(array: List[int] = None, size: int = 0) -> int window_start, max_, window_sum_ = 0, float("-inf"), 0 for window_end in range(len(array)): if window_end > size - 1: window_sum_ -= array[window_start] window_start += 1 window_sum_ += array[window_end] max_ = max(max_, window_sum_) return max_ assert foo(array=[1, 2, 3, 4], size=3) == 9
Salin selepas log masuk

Di sini kita mungkin melihat, apabila kita membina subarray panjang saiz, kita mula menolak elemen pertama daripada jumlah tetingkap, perkara yang membolehkan kita menggunakan semula pengiraan dari langkah sebelumnya.

Sekarang, kami mungkin mengatakan kami menggunakan konsep tetingkap gelongsor dengan cekap sedangkan kami mendapat bukti yang menyemak kerumitan masa, yang dikurangkan daripada O(l*w) kepada O(l), dengan l ialah jumlah tetingkap yang akan kami gelongsor.

Idea utama yang ingin saya ketengahkan, konsep tetingkap gelongsor bukan hanya tentang menghiris yang boleh dilelang dengan tetingkap saiz tertentu.

Izinkan saya memberi anda beberapa masalah, di mana kita akan belajar cara mengesan masalah itu mungkin melibatkan konsep tetingkap gelongsor serta apa sebenarnya yang mungkin anda lakukan dengan tingkap itu sendiri.

Gambaran Keseluruhan Masalah

Memandangkan saya bercakap di sini hanya tentang konsep, saya akan melangkau "cara mengira sesuatu di dalam tetingkap".

Masalah satu

Diberi tatasusunan, cari purata semua subarray bersebelahan saiz K di dalamnya.

  1. Tingkap gelongsor ? - subarray bersebelahan kata kunci pertama, bermakna kita harus menjaga tingkap, yang akan mewakili subarray bersebelahan.
  2. Adakah kita tahu saiz tingkap gelongsor? - yeap, K, kita dapat saiz tingkap, yang sepatutnya panjang K.
  3. Apakah sebenarnya yang kita patut urus/semak dalam tetingkap gelongsor? - cari purata bagi...

Bagus, sekarang kita mungkin mentakrifkan pendekatan dengan cara: lelaran ke atas tatasusunan input dengan tetingkap saiz K. Pada setiap lelaran kira purata tetingkap ...

Masalah dua

Diberi tatasusunan nombor positif dan nombor positif K, cari jumlah maksimum mana-mana subray bersebelahan saiz K.

  1. Tingkap gelongsor ? - subarray bersebelahan sekali lagi, kata kunci pertama, bermakna kita harus menjaga tingkap, yang akan mewakili subarray bersebelahan.
  2. Adakah kita tahu saiz tingkap gelongsor? - yeap, K, kita dapat saiz tingkap, yang sepatutnya panjang K.
  3. Apakah sebenarnya yang kita patut urus/semak dalam tetingkap gelongsor? - .. Jumlah ...

Sekarang: lintasi tatasusunan input dengan tetingkap bersaiz K. Pada setiap lelaran kira jumlah tetingkap ...

Masalah ketiga

Diberi tatasusunan nombor positif dan nombor positif S, cari panjang subarray bersebelahan terkecil yang jumlahnya lebih besar daripada atau sama dengan S.

  1. 引き違い窓 ? - 連続部分配列、最初のキーワードです。これは、連続部分配列を表すウィンドウを処理する必要があることを意味します。
  2. 引き違い窓のサイズを知っていますか? - 実際にはいいえ、それを理解する必要があります。
  3. スライディング ウィンドウ内で正確に何を管理/確認する必要があるのでしょうか? - ... 合計は S に対して >= です ...

ここで、アプローチを次のように定義します。「まず、入力配列を反復処理し、条件を満たす最初のウィンドウを構築します (合計が S に対して >= である)。完了したら、ウィンドウを移動し、ウィンドウの開始と管理を行います」終わります…」

問題 4

文字列が与えられた場合、その中で K 個以下の異なる文字を含む最長の部分文字列の長さを見つけます。

    引き違い窓 ? - 最長の部分文字列、最初のキーワード。部分文字列を表すウィンドウを処理する必要があることを意味します。
  1. 引き違い窓のサイズを知っていますか? - いいえ、それを理解する必要があります。
  2. スライディング ウィンドウ内で正確に何を管理/確認する必要があるのでしょうか? - ... 個別の文字の量 ...
ここでのアプローチはもう少し複雑なので、ここでは省略します。

問題 5

各整数が果樹を表す整数の配列が与えられた場合、2 つのバスケットが与えられ、目標は各バスケットに最大数の果物を入れることです。唯一の制限は、各バスケットに 1 種類のフルーツのみを入れることです。

どのツリーからでも開始できますが、一度開始したツリーをスキップすることはできません。各木から 1 つの果物を収穫できなくなるまで収穫します。つまり、3 番目の果物の種類から収穫する必要があるときに停止します。
両方のバスケット内の果物の最大数を返す関数を作成します。

それほど明白ではないようです。まず条件を単純化しましょう。

入力配列があります。配列には 2 つの異なる数字 (バケット) のみが含まれる場合があります。長さが最大になるような連続した部分配列を見つけるように求められます。

これで、スライディング ウィンドウのコンセプトを使用できる可能性があることが簡単にわかりました。

    引き違い窓 ? - 連続したサブ配列
  1. 引き違い窓のサイズを知っていますか? - いいえ、それを理解する必要があります。
  2. スライディング ウィンドウ内で正確に何を管理/確認する必要があるのでしょうか? - ... 数字が区別できるかどうか、およびウィンドウの長さ ...
問題 6

文字列とパターンが与えられた場合、その文字列にパターンの順列が含まれているかどうかを調べます。

まず、オリジナルとパターンの2つの弦があります。何らかの方法でオリジナルとパターンを比較したことがわかり、そのアイデアに至ったので、パターンのサイズのウィンドウを構築し、さらに順列チェックを実行する必要があります。つまり、スライディング ウィンドウのコンセプトを使用する可能性があります。

アウトロ

スライディング ウィンドウを扱うときは、次の質問に留意してください:

    窓の大きさわかりますか
  • ウィンドウの作り方は理解できましたか
  • ウィンドウを移動/縮小する方法は理解できましたか
  • 有効/無効ウィンドウとは何か理解していますか
  • 無効なウィンドウを有効なウィンドウにする方法は理解できましたか

Atas ialah kandungan terperinci Siri Bercakap dengan Anda #2. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!