Meditasi LeetCode: Subarray Produk Maksimum

王林
Lepaskan: 2024-08-28 06:03:33
asal
455 orang telah melayarinya

LeetCode Meditations: Maximum Product Subarray

Penerangan untuk Subarray Produk Maksimum ialah:

Memandangkan nombor tatasusunan integer, cari subarray yang mempunyai produk terbesar dan kembalikan produk.

Kes ujian dijana supaya jawapan akan dimuatkan dalam 32-bit integer.

Contohnya:

Input: nums = [2, 3, -2, 4]
Output: 6
Explanation: [2, 3] has the largest product 6.
Salin selepas log masuk
Input: nums = [-2, 0, -1]
Output: 0
Explanation: The result cannot be 2, because [-2, -1] is not a subarray.
Salin selepas log masuk

Kini, menggunakan pendekatan kekerasan, kita boleh menyelesaikannya dengan gelung bersarang.

Memandangkan kita akhirnya perlu mendapatkan produk maksimum, mari kita ketahui nilai maksimum dalam tatasusunan dahulu:

let max = Math.max(...nums);
Salin selepas log masuk

Kemudian, semasa kita meneliti setiap nombor, kita boleh terus mendarabkannya dengan nombor lain yang tinggal, membina jumlah. Setelah jumlah ini melebihi maksimum, kami boleh mengemas kini maksimum untuk menunjukkan nilai baharu ini:

for (let i = 0; i < nums.length; i++) {
  let total = nums[i];
  for (let j = i + 1; j < nums.length; j++) {
    total *= nums[j];
    if (total > max) {
      max = total;
    }
  }
}
Salin selepas log masuk

Pada akhirnya, kami hanya boleh mengembalikan maks. Jadi, percubaan pertama penyelesaian akhir kami kelihatan seperti ini:

function maxProduct(nums: number[]): number {
  let max = Math.max(...nums);
  for (let i = 0; i < nums.length; i++) {
    let total = nums[i];
    for (let j = i + 1; j < nums.length; j++) {
      total *= nums[j];
      if (total > max) {
        max = total;
      }
    }
  }

  return max;
}
Salin selepas log masuk

Kerumitan masa dan ruang

Kerumitan masa ialah O(n2)O(n^2) O(n2) kerana kita mempunyai gelung bersarang, melakukan operasi berterusan untuk setiap nombor untuk setiap satu yang kita ulangi.
Kerumitan ruang adalah O(1)O(1) O(1) kerana kami tidak memerlukan storan tambahan.

Sekali lagi, ini hanyalah percubaan kekerasan. Jadi, mari kita tarik nafas panjang, dan lihat penyelesaian lain.


Idea dengan penyelesaian baharu ini adalah untuk mengekalkan dua nilai berbeza untuk maksimum dan minimum semasa kita meneliti setiap nombor dalam tatasusunan. Sebabnya ialah mengendalikan nilai negatif, seperti yang akan kita lihat sebentar lagi.

Pertama, mari kita mulakan dengan memulakan nilai ini: kita akan mempunyai currentMax, currentMin dan hasil, yang semuanya pada mulanya menunjuk kepada nilai pertama dalam tatasusunan:

let currentMax = nums[0];
let currentMin = nums[0];
let result = nums[0];
Salin selepas log masuk

Sekarang, bermula dengan nombor kedua, kami akan mengulangi setiap nilai, mengemas kini nombor maksimum semasa dan nombor minimum semasa serta keputusan (yang akan menjadi maksimum terakhir) semasa kami pergi:

for (let i = 1; i < nums.length; i++) {
  currentMax = Math.max(nums[i], nums[i] * currentMax);
  currentMin = Math.min(nums[i], nums[i] * currentMin);

  result = Math.max(result, currentMax);
}
Salin selepas log masuk

Namun, sebelum itu, mari kita lihat contoh perkara yang boleh berlaku jika kita berbuat demikian sahaja.

Katakan tatasusunan kami ialah [-2, 3, -4]. Pada mulanya, currentMax dan currentMin adalah kedua-duanya -2. Kini, untuk mengemas kini currentMax, kami mempunyai dua pilihan: sama ada nombor semasa atau nombor semasa didarab dengan currentMax:

Math.max(3, 3 * -2)
Salin selepas log masuk

Jelas sekali, ini adalah pilihan pertama, jadi Max semasa kami kini 3.
Untuk mengemas kini currentMin, kami juga mempunyai dua pilihan:

Math.min(3, 3 * -2)
Salin selepas log masuk

Ia sekali lagi jelas, -6. Buat masa ini, nilai kami kelihatan seperti ini:

currentMax // 3
currentMin // -6
Salin selepas log masuk

Bersambung ke nombor seterusnya. Kami mempunyai dua pilihan untuk currentMax:

Math.max(-4, -4 * 3)
Salin selepas log masuk

Dengan sendirinya, ia mestilah -4, tetapi melihat tatasusunan kami, kami melihat bahawa ini tidak berlaku. Memandangkan mendarab dua nilai negatif menghasilkan nilai positif, Maks semasa kita hendaklah 24 (-2 * 3 * -4).

Note
If we were to multiply it with currentMin, we reach this value: -4 * -6 = 24.

Also, let's look at our currentMin options:

Math.min(-4, -4 * -6)
Salin selepas log masuk

This has to be -4 again, but something feels off.

The catch is that when we have negative numbers consecutively, our sign alternates, which affects the maximum result we need. That's why we're keeping track of the minimum value in the first case: to keep track of the sign.

Since the issue is just alternating signs, we can simply swap the maximum and minimum values when we're looking at a negative number before updating those values:

if (nums[i] < 0) {
  [currentMax, currentMin] = [currentMin, currentMax];
}
Salin selepas log masuk

Also, note that we're taking the product of each previous subarray as we go, essentially solving a smaller portion of the problem.

And that's it, our final solution looks like this:

function maxProduct(nums: number[]): number {
  let currentMax = nums[0];
  let currentMin = nums[0];
  let result = nums[0];

  for (let i = 1; i < nums.length; i++) {
    if (nums[i] < 0) {
      [currentMax, currentMin] = [currentMin, currentMax];
    }

    currentMax = Math.max(nums[i], nums[i] * currentMax);
    currentMin = Math.min(nums[i], nums[i] * currentMin);

    result = Math.max(result, currentMax);
  }

  return result;
}
Salin selepas log masuk

Time and space complexity

The time complexity for this solution is O(n)O(n) O(n) because we go through each number once doing a constant operation.

Note
Math.max() and Math.min() are constant operations here, since we're comparing two values only. However, if we were to find max or min of a whole array, it would be O(n)O(n) O(n) as the time complexity of the operation would increase proportionately to the size of the array.

The space complexity is O(1)O(1) O(1) since we don't need any additional storage.


The next problem on the list is called Word Break. Until then, happy coding.

Atas ialah kandungan terperinci Meditasi LeetCode: Subarray Produk Maksimum. 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
Tutorial Popular
Lagi>
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!