Learnitweb

Advanced Complexity Evaluation: Addition, Multiplication, Logarithms, and Strings

In this tutorial, we’ll dive deeper into algorithm complexity, focusing on common operations such as addition, multiplication, logarithmic algorithms, and the role of string manipulation in evaluating time complexity.

1. Complexity of Addition and Multiplication

Let’s start by analyzing sequential and nested loops.

Example: Sequential Loops

Suppose we have the following scenario:

  • One loop iterates over array A of length a
  • Another loop iterates over array B of length b

These loops run sequentially, not nested. So we simply add their individual complexities:

 T(a, b) = a + b

In Big-O notation:

 T(a, b) = O(a + b)

Example: Nested Loops

Now consider a different case where the inner loop runs for every iteration of the outer loop:

  • Outer loop runs a times
  • Inner loop runs b times per outer iteration

This leads to:

 T(a, b) = a \times b

In Big-O notation:

 T(a, b) = O(a \times b)

So, use addition when operations are sequential and multiplication when operations are nested.

2. Logarithmic Time Complexity: Binary Search

Let’s understand logarithmic complexity using the binary search algorithm.

Binary Search Overview

Given a sorted array of size n, binary search follows these steps:

  1. Check the middle element.
  2. If target is smaller, search left half.
  3. If target is larger, search right half.
  4. Repeat until the element is found or subarray size becomes 1.

Each step halves the number of elements to process.

Complexity Analysis

Suppose the array size is n = 16.

Each iteration reduces the problem size by half:

  • Iteration 1: n = 16
  • Iteration 2: n = 8
  • Iteration 3: n = 4
  • Iteration 4: n = 2
  • Iteration 5: n = 1

So, number of operations k needed is approximately:

 k = \log_2 n + 1

Hence,

 T(n) = O(\log n)

This logarithmic time complexity arises in many algorithms that divide the problem in half each time.

3. Impact of Strings on Complexity

3.1 Comparing Strings

When comparing strings like:

if (s1 > s2)

The algorithm compares each character one-by-one until a difference is found. In the worst case, all characters are compared.

If n is the length of the string, then:

 T(n) = O(n)

3.2 String Concatenation

In many languages (Java, JavaScript, C#), strings are immutable. So concatenating strings creates a new string each time:

s3 = s1 + s2

Steps:

  1. Calculate total length n + k
  2. Allocate new array
  3. Copy characters from s1
  4. Copy characters from s2
  5. Create new string

Hence,

 T(n, k) = O(n + k)

3.3 Substring Operation

When extracting a substring:

s2 = s1.substring(start, end)

Steps:

  1. Calculate new length: n - k
  2. Allocate array of size n - k
  3. Copy characters
  4. Create new string

Thus:

 T(n, k) = O(n - k)

And in worst-case (where k = 1), it still simplifies to:

 O(n)

4. Repeated String Concatenation in Loops

Consider this code:

String s = "";
for (int i = 0; i < n; i++) {
    s = s + "A";
}

Each iteration creates a longer string:

IterationString LengthOperation Cost
111
222
333
nnn

The total time complexity:

 T(n) = 1 + 2 + 3 + \cdots + n = \frac{n(n+1)}{2}

Therefore,

 T(n) = O(n^2)

5. Summary of Key Concepts

Sequential vs Nested Loops

  • SequentialO(a + b)
  • NestedO(a \times b)

Logarithmic Algorithms

  • Halving each time → O(\log n)