<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Временная сложность O(n): полный гайд с примерами на JavaScript]]></title><description><![CDATA[<p dir="auto">Сложность O(n) описывает алгоритмы, где время выполнения растёт пропорционально размеру входных данных. Если входных элементов 100 — алгоритм сделает примерно 100 операций. Если 10 000 — сделает примерно 10 000 операций.</p>
<p dir="auto"><strong>Зачем нужно это знать?</strong> Потому что разница между хорошим и плохим алгоритмом может быть в миллионы раз. Обработка данных за 0.1 секунду или за час — результат одного неправильного выбора алгоритма.</p>
<h2>Как считается сложность</h2>
<p dir="auto">Сложность O(n) означает: количество операций примерно равно n (количеству элементов).</p>
<p dir="auto">При n = 100: операций ~100<br />
При n = 1000: операций ~1000<br />
При n = 1 000 000: операций ~1 000 000</p>
<p dir="auto">Линейная зависимость — просто и предсказуемо.</p>
<h2>Пример 1: Простой цикл по массиву</h2>
<pre><code class="language-javascript">function findMax(arr) {
  let max = arr[0];
  
  for (let i = 1; i &lt; arr.length; i++) {
    if (arr[i] &gt; max) {
      max = arr[i];
    }
  }
  
  return max;
}

const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
console.log(findMax(numbers)); // 9
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Цикл <code>for</code> проходит по всем элементам массива ровно один раз. Если в массиве 8 элементов — 8 итераций. Если 1000 элементов — 1000 итераций. Это и есть O(n).</p>
<p dir="auto"><strong>Как это работает:</strong></p>
<ol>
<li>Берём первый элемент как начальное максимальное значение</li>
<li>Проходим по остальным элементам</li>
<li>Если текущий элемент больше максимума — обновляем максимум</li>
<li>Возвращаем результат</li>
</ol>
<h2>Пример 2: Поиск элемента в массиве</h2>
<pre><code class="language-javascript">function search(arr, target) {
  for (let i = 0; i &lt; arr.length; i++) {
    if (arr[i] === target) {
      return i;
    }
  }
  return -1;
}

const colors = ['red', 'green', 'blue', 'yellow'];
console.log(search(colors, 'blue'));    // 2
console.log(search(colors, 'purple'));  // -1
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> В худшем случае (элемент в конце или отсутствует) нужно проверить все элементы.</p>
<p dir="auto"><strong>В лучшем случае:</strong> O(1) — элемент в начале, нашли сразу.<br />
<strong>В среднем случае:</strong> O(n) — примерно на середине.<br />
<strong>В худшем случае:</strong> O(n) — элемента нет или в конце.</p>
<p dir="auto">Обычно говорят о худшем случае, поэтому это O(n).</p>
<h2>Пример 3: Суммирование всех элементов</h2>
<pre><code class="language-javascript">function sum(arr) {
  let total = 0;
  
  for (let i = 0; i &lt; arr.length; i++) {
    total += arr[i];
  }
  
  return total;
}

const prices = [100, 250, 50, 300];
console.log(sum(prices)); // 700
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Нужно посетить каждый элемент ровно один раз, чтобы добавить его к сумме. Нет способа посчитать сумму без обхода всех элементов.</p>
<h2>Пример 4: Фильтрация массива</h2>
<pre><code class="language-javascript">function filterPositive(arr) {
  const result = [];
  
  for (let i = 0; i &lt; arr.length; i++) {
    if (arr[i] &gt; 0) {
      result.push(arr[i]);
    }
  }
  
  return result;
}

const numbers = [-5, 10, -3, 8, 0, -1, 15];
console.log(filterPositive(numbers)); // [10, 8, 15]
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Проходим по всем элементам один раз, проверяем условие для каждого.</p>
<p dir="auto"><strong>То же самое для встроенного метода:</strong></p>
<pre><code class="language-javascript">const positive = numbers.filter(x =&gt; x &gt; 0); // Тоже O(n)
</code></pre>
<p dir="auto">Встроенные методы <code>.filter()</code>, <code>.map()</code>, <code>.forEach()</code> — все они O(n), потому что внутри есть цикл по всем элементам.</p>
<h2>Пример 5: Подсчёт вхождений элемента</h2>
<pre><code class="language-javascript">function countOccurrences(arr, target) {
  let count = 0;
  
  for (let i = 0; i &lt; arr.length; i++) {
    if (arr[i] === target) {
      count++;
    }
  }
  
  return count;
}

const items = ['apple', 'banana', 'apple', 'cherry', 'apple'];
console.log(countOccurrences(items, 'apple')); // 3
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Нужно проверить все элементы, чтобы посчитать их правильно.</p>
<h2>Пример 6: Проверка содержимого (includes)</h2>
<pre><code class="language-javascript">function contains(arr, value) {
  for (let i = 0; i &lt; arr.length; i++) {
    if (arr[i] === value) {
      return true;
    }
  }
  return false;
}

const fruits = ['apple', 'banana', 'cherry'];
console.log(contains(fruits, 'banana'));  // true
console.log(contains(fruits, 'orange'));  // false
</code></pre>
<p dir="auto"><strong>То же самое с методом:</strong></p>
<pre><code class="language-javascript">fruits.includes('banana'); // Тоже O(n)
</code></pre>
<h2>Пример 7: Копирование массива</h2>
<pre><code class="language-javascript">function copyArray(arr) {
  const copy = [];
  
  for (let i = 0; i &lt; arr.length; i++) {
    copy.push(arr[i]);
  }
  
  return copy;
}

const original = [1, 2, 3];
const duplicate = copyArray(original);
console.log(duplicate); // [1, 2, 3]
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Нужно посетить каждый элемент, чтобы скопировать его.</p>
<h2>Пример 8: Поиск минимума и максимума одновременно</h2>
<pre><code class="language-javascript">function findMinMax(arr) {
  let min = arr[0];
  let max = arr[0];
  
  for (let i = 1; i &lt; arr.length; i++) {
    if (arr[i] &lt; min) {
      min = arr[i];
    }
    if (arr[i] &gt; max) {
      max = arr[i];
    }
  }
  
  return { min, max };
}

const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
console.log(findMinMax(numbers)); // { min: 1, max: 9 }
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Один цикл по всем элементам. Неважно, что операций внутри цикла больше одной — мы проходим каждый элемент один раз.</p>
<h2>Пример 9: Сложное условие в цикле (всё ещё O(n))</h2>
<pre><code class="language-javascript">function processData(arr) {
  let result = 0;
  
  for (let i = 0; i &lt; arr.length; i++) {
    // Много операций, но всё равно O(n)
    if (arr[i] &gt; 0) {
      result += arr[i] * 2;
      result = Math.sqrt(result);
      result += arr[i];
    } else {
      result -= arr[i];
    }
  }
  
  return result;
}

console.log(processData([1, 2, 3]));   // O(n)
console.log(processData([1, 2, 3, 4, 5])); // Примерно в 1.67 раз дольше
</code></pre>
<p dir="auto"><strong>Почему O(n)?</strong> Важен количество итераций цикла, не количество операций внутри. Даже если внутри 100 операций, это всё ещё O(n), только с большей константой.</p>
<h2>Пример 10: Вложенные циклы (это НЕ O(n)!)</h2>
<pre><code class="language-javascript">// НЕПРАВИЛЬНО для O(n):
function findPairs(arr) {
  const pairs = [];
  
  for (let i = 0; i &lt; arr.length; i++) {
    for (let j = 0; j &lt; arr.length; j++) {
      if (arr[i] + arr[j] === 10) {
        pairs.push([arr[i], arr[j&rsqb;&rsqb;);
      }
    }
  }
  
  return pairs;
}

console.log(findPairs([3, 7, 2, 8, 5])); // Вложенные циклы = O(n²), НЕ O(n)
</code></pre>
<p dir="auto"><strong>Это O(n²), а не O(n)!</strong> Если в массиве 1000 элементов, будет 1 000 000 итераций. Это качественно иначе, чем 1000 итераций.</p>
<h2>O(n) vs O(n²): реальное сравнение</h2>
<p dir="auto">Давайте увидим разницу:</p>
<pre><code class="language-javascript">// O(n) — хороший алгоритм
function linearSearch(arr, target) {
  for (let i = 0; i &lt; arr.length; i++) {
    if (arr[i] === target) return i;
  }
  return -1;
}

// O(n²) — плохой алгоритм
function quadraticSearch(arr, target) {
  for (let i = 0; i &lt; arr.length; i++) {
    for (let j = 0; j &lt; arr.length; j++) {
      if (arr[j] === target) return j;
    }
  }
  return -1;
}

// Тест времени
const bigArray = Array.from({length: 10000}, (_, i) =&gt; i);
const target = 9999;

console.time('O(n)');
for (let k = 0; k &lt; 1000; k++) linearSearch(bigArray, target);
console.timeEnd('O(n)');
// Примерно 20-30ms

console.time('O(n²)');
for (let k = 0; k &lt; 10; k++) quadraticSearch(bigArray, target); // Только 10 раз!
console.timeEnd('O(n²)');
// Примерно 5000-10000ms — в 100+ раз дольше!
</code></pre>
<p dir="auto">Видите разницу? O(n²) убивает производительность.</p>
<h2>Практические советы</h2>
<p dir="auto"><strong>Когда вы видите один простой цикл — это обычно O(n):</strong></p>
<pre><code class="language-javascript">for (let i = 0; i &lt; arr.length; i++) { ... }
</code></pre>
<p dir="auto"><strong>Когда вы видите вложенные циклы — это обычно O(n²) или хуже:</strong></p>
<pre><code class="language-javascript">for (let i = 0; i &lt; arr.length; i++) {
  for (let j = 0; j &lt; arr.length; j++) { ... }
}
</code></pre>
<p dir="auto"><strong>Встроенные методы и их сложность:</strong></p>
<ul>
<li><code>.find()</code>, <code>.filter()</code>, <code>.map()</code>, <code>.forEach()</code> — O(n)</li>
<li><code>.includes()</code>, <code>.indexOf()</code> — O(n)</li>
<li><code>.sort()</code> — O(n log n) (не O(n), но лучше чем O(n²))</li>
<li><code>.push()</code> на конец массива — O(1)</li>
<li><code>.shift()</code>, <code>.unshift()</code> на начало массива — O(n) (нужно сдвигать элементы)</li>
</ul>
<h2>Почему O(n) — часто хороший выбор</h2>
<p dir="auto">O(n) часто является оптимальным решением, потому что:</p>
<ol>
<li>
<p dir="auto"><strong>Нужно посетить все элементы.</strong> Если вам нужна информация о всех элементах (сумма, поиск элемента, фильтрация), вы не можете быстрее, чем O(n).</p>
</li>
<li>
<p dir="auto"><strong>Это масштабируется.</strong> 1 млн элементов за 100ms вполне приемлемо.</p>
</li>
<li>
<p dir="auto"><strong>Просто для понимания.</strong> Один цикл легче отладить и понять, чем сложные структуры данных.</p>
</li>
</ol>
<h2>Заключение</h2>
<p dir="auto">O(n) — это линейная сложность, где время растёт пропорционально размеру входных данных. Это один из основных видов сложности, который вам встретится в реальных задачах.</p>
<p dir="auto"><strong>Запомните:</strong></p>
<ul>
<li>O(n) = один цикл по всем элементам</li>
<li>O(n) часто оптимально, когда нужно посетить все элементы</li>
<li>O(n²) = вложенные циклы, это плохо для больших данных</li>
<li>Всегда думайте о сложности, выбирая алгоритм</li>
</ul>
]]></description><link>https://forum.exlends.ru/topic/387/vremennaya-slozhnost-o-n-polnyj-gajd-s-primerami-na-javascript</link><generator>RSS for Node</generator><lastBuildDate>Sat, 17 Oct 2026 03:12:16 GMT</lastBuildDate><atom:link href="https://forum.exlends.ru/topic/387.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 09 Jan 2026 20:22:36 GMT</pubDate><ttl>60</ttl></channel></rss>