ICP Unit-1 Updated V6
ICP Unit-1 Updated V6
Unit-1
Dept. of CSE, GITAM Visakhapatnam
June 2025
Contents
1 Time and Space Complexity 3
1.1 Input Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3 Experimental Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.1 Online Judge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.2 Time & Space Experimental Tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3.3 Measure Execution Time with the given input size . . . . . . . . . . . . . . . . . . . . 7
1.3.4 Exercise: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
4 Analysis of Loop 13
4.1 Single Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.1.1 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.2 Nested Loop Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.3 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1
6.3.3 Space Complexity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
6.4 Binary Search Common Mistake in Competitive Coding . . . . . . . . . . . . . . . . 21
6.5 Linear Search vs Binary Search: Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6.6 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6.6.1 Time Complexity: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.6.2 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
7 Bit Manipulation 22
7.1 Key Bitwise Operators (C++, Python, Java) . . . . . . . . . . . . . . . . . . . . . . . 22
7.2 Advantages of Bit Manipulation? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
7.3 Decimal Vs Bit Manipulation: A Quick Comparison . . . . . . . . . . . . . . . . . . . . . . . 23
7.4 Common Bit Manipulation Operations (Verify with Examples) . . . . . . . . . . . . . . . . . 23
7.5 Examples of Bit Manipulation Tricks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
7.5.1 Example 1: Check if a number is power of 2 . . . . . . . . . . . . . . . . . . . . . . . . 23
7.5.2 Example 2: Counting 1 Bits (LeetCode 191) . . . . . . . . . . . . . . . . . . . . . . . 23
7.5.3 Example 3: Set the k-th Bit. Making k-th bit 1 . . . . . . . . . . . . . . . . . . . . . . 23
7.5.4 Example 4: Toggle/Reverse the k-th Bit (LeetCode 190) . . . . . . . . . . . . . . . . 24
7.6 Classic Competitive Problems Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7.6.1 Problem 1: Single Number (Leetcode 136) . . . . . . . . . . . . . . . . . . . . . . . . 24
7.6.2 Problem 2: Subset Generation (Leetcode 78) . . . . . . . . . . . . . . . . . . . . . . . 24
7.6.3 Problem 3: Counting Bits (Leetcode 338) . . . . . . . . . . . . . . . . . . . . . . . . 24
7.7 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2
1 Time and Space Complexity
• Time Complexity: It estimates how the execution time of an algorithm increases as the input size
n increases. It is denoted as T(n)
– Example: O(1), O(n), O(n2 ), etc1
∗ O(1) Constant Time – Independent of n
∗ O(n) Linear Time
∗ O(n2 ) Quadric Time
– T(n) also depends on the number of key operations that are performed in a given algorithm. For
example, in searching, the key operation is comparison. In sorting, it is the number of swaps.
• Space Complexity: It estimates how much extra memory (not counting input) an algorithm needs
as input size n increases. It is denoted as S(n) in general or M(n)
– Total Space = Input Space (given) + Auxiliary Space (extra used)
– We usually analyze auxiliary space.
– Example: Same as Time – O(1), O(n), O(n2 ), etc
Reason: Always does one operation, regardless of array size Uses only one extra variable (maxVal), regardless of n
Analogy Picking the first book from a shelf regardless of the Finding the tallest student in a class
shelf size
Let’s Think S(n) = ? T(n) = ?
O(n)
Reason: It visits each element once, i.e n operations Allocates an extra array of size n
Analogy Reading all books one by one from a shelf Making an exact photocopy of each page in a book
Let’s Think S(n) = ? T(n) = ?
1 There √
exist several other complexities such as n, n!, log2 n, n log2 n, 2n
3
O(n2 )
return is_friend
Reason: Nested loops each run n times, total operations: n × Uses an auxiliary 2D array of n X n
n = n2
Analogy Comparing each student with every other student. Listing each student with every other student, if they
are friends.
Let’s Think S(n) = ? T(n) = ?
O(log2 n)
Reason Each iteration halves the search space log2 (n) itera-
Each recursive call adds a new frame to the call stack,
tions with depth log2 (n)
Analogy Looking for a word in a very large physical dictionary
Calling an assistant each time to check if the word is
in the middle of this section
Let’s Think S(n) = ? T(n) = ?
Table 1: Examples: Code demonstration for T(n) and S(n)
2 *If individual digits are involved then n = log (N umber). b = base of any number. In cases involving numerical inputs,
b
the effective input size ’n’ can depend on the specific implementation details of the algorithm used to solve the problem.
4
Combinatorics n = # of items, but results = 2n Subset generation, permutation back-
(sub sets), n! (permutations) tracking
Lowest Common Ancestor (LCA), Longest common subsequence (LCS)
• Example Interpretation
– In Graphs, input includes both vertices and edges, so time/space complexities are usually in terms
of V + E.
∗ BFS/DFS: O(V + E)
∗ Dijkstra’s: O((V + E) log n) with priority queue
∗ Floyd-Warshall: O(n3 )
– In DP, if you’re solving a 0/1 Knapsack problem with n items and capacity W, the input size is n
+ W and table size is n × W.
∗ Fibonacci DP: T(n) = O(n)
∗ Knapsack DP: T(n) = O(nW)
– In Combinatorics, even though input is small (say n = 20), the solution space (2n = 1 million)
can be huge.
• Order of Growth:
O(1) < O(log2 n) < O(n) < O(n ∗ log2 n) < O(n2 ) < O(2n ) (1)
•
Q1) Why should we learn this order of growth while doing competitive coding which depends on the
I/P size?
Q2) How come input size n affects the time complexity? I am asking this question because, run time
depends on the # of instructions to be executed. So, how n influences the # of instructions?
5
1.2 Exercise
Consider the input size n = [ 1, 2, 4, 10, 20, 25, 50, 100, 103 , 108 ] and prepare a table to validate
the Equation 1.
a) Identify the minimum input size (n0 ) for which Equation 1 holds good.
√
b) Find the Proper place of n and n! in the Equation 1.
.
The Space and Time complexity Analysis can be done in two ways
• Experimental Analysis
• Asymptotic/Theoretical Analysis (Already discussed at the beginning)
• It helps to choose algorithm(s) for a given input size to solve a particular problem.
• A modern computer can perform about 108 to 109 basic operations per second [1, 2]. Based on this,
the maximum input size depends on the algorithm’s time complexity and the available time.
• Table 4 (from Book CP4 by Halim et.el [2]) shows accepted (AC) time complexities depending on input
size.
6
1.3.1 Online Judge
• It is a software system or platform used to automatically evaluate the correctness, performance, and
resource usage (time and space) of submitted code solutions to the programming problems.
• It is used in competitive coding to measure:
– Correctness of output
– Time taken (Execution Time) → for Time Complexity
– Memory used (RAM): for Space Complexity
– Edge case handling, runtime errors, or crashes
• Examples of Popular Online Judges: Codeforces, LeetCode, AtCoder, HackerRank, Google Kick Start
/ Code Jam (discontinued)
• Common Features:
Feature Description
Automatic Grading Verifies correctness of output against multiple test cases
Time Limit Enforcement Typically 1–2 seconds per test case
Memory Limit Enforcement Usually in MBs (e.g., 256MB, 512MB)
Language Support C++, Python, Java, Go, Rust, etc.
Feedback Accepted, TLE (Time Limit Exceeded), MLE (Memory Limit Ex-
ceeded), WA (Wrong Answer), RE (Runtime Error), CE (Compi-
lation Error)
Let’s demonstrate this experimental analysis. Consider the following examples in the given table, which
have already been discussed in Table 1
Table 6: Three different functions showing T(n) = O(1), O(n), and O(n2 )
import time
start = time.time()
# Place your function Here
7
end = time.time()
total_runTime = end - start
print(total_runTime)
Example: Source Code to find time Click to toggle (Hide/Show)
The actual execution time Vs input size of the methods given in the Table 6 is observed in Table 7
8
1.3.4 Exercise:
a) Use time function as given in the Table 5 to compute and plot experimental time complexity, T(n) vs
Input size n = [ 100, 103 , 106 ] of the iterative binary search (Refer Table 1) and Linear search
algorithm. The answer should follow the template of Table ??. Hint: To generate sorted array of the
given size use the following code
def generate_sorted_array(size):
return list(range(size))
b) Use the space function as given in the Table 5 to compute experimental space complexity, S(n) Vs Input
size n of the algorithms given in Table 6
c) Try using any one of the profilers (Refer Table 5) to visualize the experimental time complexity of the
algorithms in the Table 6
2.1 Example
Checking whether a decimal number (where, input size n <= 1010 ) is prime within 1 sec.
√Let’s consider two solution approaches, Approach-1 incurs time O(n) and Approach-2 incurs time
O( n). If the input size n ≤ 108 then Approach-1 may solve it within 1 sec (Refer Table 4 and 3).
However, if input size n ≥ 108 then it may take more than 1 sec, which is not permissible as per the problem
statement. So, your program should throw the error TLE. In this scenario, your obvious choice should be
Approach-2 which can handle the input size up to 1010 without TLE error.
Source Code Example (Check Prime) Click to toggle (Hide/Show) and Refer Section 2.3
• If your code doesn’t produce output within that time, the system terminates it and reports TLE.
9
2.4 Why is TLE Important?
• TLE helps enforce efficient algorithms.
10
2.5 How to Avoid TLE?
• Analyze Time Complexity Choose an algorithm with acceptable time for input size. Refer Table ??
– n ≤ 108 : O(n) or O(n log n)
– n ≤ 104 : O(n2 ) may work
• Optimize Input/Output
• Use Fast Data Structures: set, dict, heapq, deque, etc in python
2.6 Exercise
Q.1) Test each method listed in Table 9 to check whether it results in a Time Limit Exceeded (TLE) error
under a 1-second execution limit. For each method, record the maximum input size that executes
within the time limit.
Then, write your observations by explaining the relationship between the input size, the time taken,
and the occurrence of the TLE error.
Q.2) The following Python method results in a TLE (Time Limit Exceeded) error when n = 1016 + 61. but
does not produce a TLE for n = 1018 . What could be the reason behind this behavior?
def is_prime_optimized_rootN(n):
if n <= 1:
return False
i = 2
while i * i <= n: #or while i<=sqrt(n)+1 may be avoided
if n % i == 0:
return False
i += 1
return True
11
3.2 Common Patterns with Examples
5. Binary search with wrong loop condi- Use standard binary search form
tion (low < high)
def binary_search(arr, low, high, item):
def binary_search(arr, low, high, item): while low <= high:
while low < high: mid = (low + high) // 2
mid = (low + high) // 2 if arr[mid] == item:
if arr[mid] == item: return mid
return mid #Item Found elif arr[mid] < item:
elif arr[mid] < item: low = mid + 1
low = mid + 1 else:
else: high = mid - 1
high = mid - 1 return -1 # if item is not found
return -1 # if item is not found
12
4 Analysis of Loop
In competitive coding, analyzing the loops (Single / Multiple) are often the first step to estimate time
complexity, check for Time Limit Exceeded (TLE) risks (Will be discussed in Section 2), and optimize the
solution accordingly.
• Analysis Strategy:
– Identify the number of iterations of the loop.
– Estimate work inside the loop – is it constant O(1), or some function of n?
– Calculate total time complexity.
– Verify via code (optional) using a timer to confirm feasibility.
• If there exist only a single loop in an algorithm/program which, runs for ’n’ times (that is, it may run
for n ± k times, k >= 0) and the statements/instructions under this loop incurs constant time, O(1)
then, algorithm’s complexity is treated as O(n). Some Examples of this complexity:
– Checking a Prime number
– Finding the divisors of a number
– Finding ab
– Finding the frequency of each item in an array
– Checking if the array is sorted
– Searching for an item in an array (Linear search)
• If the loop condition is i ≤ n and loop control variable i is doubled or halfed each time, i.e i *= 2
or i //= 2 then T(n) = O(log2 (n))
– Finding ab
– Searching for an item in an array (Binary search, Refer Table 1)
– Euclidean Algorithm for GCD
The following table presents a comparison of various algorithms that address the same problem, high-
lighting their differences in computational complexity.
13
Table 9: Simple Loop Analysis and Identifying T(n)
Checking prime
√
O(n) O( n)
Finding ab
4.1.1 Exercise
Q.1) For each method listed in Table 10, determine the time complexity and auxiliary space com-
plexity in Big-O notation. Additionally, clearly state the objective of each method by describing
the expected output for a given sample input.
14
• If Some work is of O(1)
• If Some work is of O(n)
def generate_strings(n):
for i in range(2**n):
// Some work
Note: In this table, n, a, and b are decimal numbers. arr denotes an array
• Understanding when and how you can optimize nested loops helps avoid TLE (Time Limit
Exceeded) and win contests!
• Goal:
– Detect inefficient nested loops and see if you can replace them with a more optimized solution
using better data structures or mathematical insight.
2
let’s explore some classic
√ examples, given in Table 11 where O(n ) solutions can be optimized to
O(n), O(log2 n), or even O( n).
15
Table 11: Nested Loop Optimizations: Naive Vs Optimized Code
Count frequency of
all divisors up to n for i in range(1, n+1): for i in range(1, n+1):
for j in range(1, i+1): for j in range(i, n+1, i):
if i % j == 0: div_count[j] += 1
div_count[i] += 1 # Optimized: (O(n log n))
Number of Distinct
Pairs (i, j) where i * count = 0 count = 0
j≤n for i in range(1, n+1): i = 1
for j in range(1, n+1): while i <= n:
if i * j <= n: count += n // i
count += 1 i += 1
# Optimized: O(sqrt(n))
4.3 Exercise
Refer the code snippets given in Table 12 and answer the following
Q.1) Given an array of size n, count the number of pairs (i, j) such that i < j and arr[i] + arr[j] is
even.
(a) Write a brute-force solution using nested loops.
(b) Analyze its time complexity.
(c) Can you optimize it to O(n)? If yes, how?
Q.2) Analyze the time complexity of the following code ( Table 12, Q.2) and suggest an optimization if
possible
Q.3) Given an n x n sorted 2D matrix (each row and column is sorted), find whether a given number x
exists in the matrix.
Analyze the naive approach as given in the Table 12 and write an optimized code.
Q.4) Analyze the following code (Table 12, Q.4)
(a) What is the objective of this code?
(b) What is its Time complexity?
(c) Optimize the code so that T(n) will be O(n log n)
16
Q.5) Given a number n, count how many pairs (i, j) exist such that i divides j. Where, 1 ≤ i, j ≤ n.
The brute force approach is given below.
Table 12: Code snippets associated with the Exercise in Section 4.3
Standard Bubble Sort (Inefficient Version) Optimized Bubble Sort (Efficient Version)
Always runs n(n-1)/2 comparisons, even if the array is already The swapped flag allows early exit if no swaps are made in a
sorted. pass — If array is already sorted.
Always T(n) = O(n2 ) Best case: O(n), Worst Case: O(n2 )
• Bubble sort is a stable sort, meaning the relative order of equal elements is preserved.
• Sorting is done in-place (An in-place sorting algorithm3 ), i.e, no extra space is used. It modifies the
input array without needing a large copy of it.
– Space complexity is O(1)
• Can be applied on tiny data set
• It is applied when, situations requiring stable, in-place sort, and performance isn’t critical
3 In-place sorting Algos: Insertion Sort, Selection Sort, Quick Sort, Heap Sort, Shell Sort
17
5.2 Merge Sort Analysis
• Merge Sort is a divide-and-conquer sorting algorithm.
• It divides the array into halves, recursively sorts them, and merges the sorted halves.
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
result.extend(left[i:])
result.extend(right[j:])
return result
• By solving:
T (n) = O(n log n)
18
5.4 Space Complexity
• Merge Sort uses O(n) auxiliary space for the temporary arrays created during merging.
• Not in-place4 (unlike Quick Sort or Heap Sort)
Note:
• Stable Sort: It preserves the order of equal elements
• Data sets that don’t fit in memory (Merge sort is used in external sorting)
• Efficient for Linked Lists
– Merge Sort can be implemented with O(1) auxiliary space on linked lists.
– Unlike arrays, you can’t easily jump across a linked list, so merge sort is ideal.
6.1.3 Limitations
• Too slow for large n (n > 108 or 106 )
• Does not leverage sorted data
4 Non
In-Place sorting Algos: Merge, Counting, Radix, Bucket, TimSort (TimSort in Python and Java, Best case O(n), Worst
Case O(nlog n))
19
6.2 Binary Search
Binary search requires the array to be sorted. It works by repeatedly halving the search space:
• Compare target with the middle element.
• If equal, done.
• If less, search the left half.
• If greater, search the right half.
20
6.4 Binary Search Common Mistake in Competitive Coding
• Forgetting that binary search requires sorted input.
• Using mid = (low + high) // 2. To avoid overflow in C, C++, and Java it is suggested to compute
mid = low + (high - low) // 2. (Can you explore the reason WHY ??)
• Failing to think in terms of searching over the answer, not just arrays.
6.6 Example
Problem: Find the smallest x such that x2 ≥ target
def find_smallest_x(target):
low, high = 0, target
answer = -1
return answer
# Example usage:
target = 20
result = find_smallest_x(target)
print(f"The smallest x such that x^2 >= {target} is {result}")
Example: For target = 20, the output is: 5. Because 52 = 25 ≥ 20 and 42 = 16 < 20.
21
6.6.1 Time Complexity:
Binary search on range [0, target] → T(n) = O(log target)
6.6.2 Exercise
Q.1) Given a sorted array and a target, return the index if found, else return the index where it would be
inserted.(LeetCode 35)
Q.2) Compute and return the integer square root of a non-negative integer x. Return the floor of the square
root.(LeetCode 69)
Q.3) Return True if a given number is a perfect square using Binary Search.(LeetCode 367)
Q.4) Find the peak index in a mountain array (first strictly increasing, then strictly decreasing). (LeetCode
852)
Q.5) As we know, binary search requires the input data to be sorted beforehand. Therefore,
if we are given an unsorted dataset, we must first sort it, which incurs a time complexity of T1(n)
(where T1(n) depends on the sorting algorithm used, typically O(n log n) for efficient algorithms).
Once sorted, binary search can be applied with a time complexity of O(log n).
Thus, the overall time complexity becomes:
T(n) = T1(n) + O(log n).
In comparison, a linear search operates directly on unsorted data with a time complexity of O(n).
Therefore, binary search (preceded by sorting) may actually take more time than linear search.
This raises an important question: What is the practical relevance of binary search in real-
world applications?
Q.6) Write a method/function to implement ternary search to find an item in a sorted array.
Hint: Here you need to divide the array into 3 parts. mid1 = left + (right - left) // 3 and
mid2 = right - (right - left) // 3
a) Analyse the code and find out the time complexity of the Ternary search?
b) Which one (Binary or Ternary) is more efficient while searching an item in a sorted array? Justify
your answer.
7 Bit Manipulation
• Bit Manipulation refers to performing operations directly on bits (binary digits) of integers using
bitwise operators.
• Bit Manipulation is essential for solving specific optimization problems, subsets generation,
parity problems, and problems related to binary representations efficiently in competitive
coding.
22
7.2 Advantages of Bit Manipulation?
Advantage Why?
Faster Operations are performed directly on hardware level (O(1))
Compact Bit-level tricks reduce complex logic to a few lines
Space-efficient Can use individual bits to represent states (bitmasking)
Elegant Solutions Solves certain problems that are cumbersome otherwise
Enables Optimization Reduces memory usage (bitsets, flags)
Reason: Power of 2 has only one bit set. For example, in n = 8 (=1000), the 4th bit is 1.
23
Reason: Here, the mask is 1 << k, shifting decimal 1 to its left k-th time. Then apply OR operation.
Reason: Here, the mask is 1 << k, shifting decimal 1 to its left k-th time. Then apply Ex-OR operation.
Input: n = 3, that is, you need to generate the subsets of [0, 1, 2] Output: [ ], [0], [1], [2], [0,
1], [0, 2], [1, 2], [0, 1, 2]
7.7 Exercise
Q.1) Given an array containing n distinct numbers in the range [0, n]. Find the one number missing from
the array. (Missing number–LeetCode 268)
Q.2) Find the sum of two integers a and b without using + or - operators.
24
Q.3) Given an array where every element appears three times except for one element which appears exactly
once. Find that unique element. I/P: nums = [2, 2, 6, 2], O/P: 6
Q.4) Given an integer, return True if it is a power of 4, otherwise return False.
Solution:
8.2 Vector
• A vector grows dynamically. It resizes (typically doubles its capacity) when the limit is reached.
• Provides array-like access but with flexibility for growth.
vec = []
vec.append(10)
vec.append(20)
vec.pop()
print(vec) # [10]
8.3 Stack
• A stack allows operations only on the top element (Last-In-First-Out).
• All the operations (push, pop, peek) incur O(1) time.
• Useful in function calls, expression evaluation, and undo mechanisms.
25
stack = []
# isEmpty
if not stack:
print("Stack is empty")
else:
print("Stack is not empty")
# Size of stack
print("Size of stack:", len(stack)) # Output: 2
8.4 Queue
• A queue adds elements at one end (rear) and removes from the other (front).
• Useful in scheduling, BFS traversal, producer-consumer problems.
• Implemented using deque
• Python Example: deque based Queue
# Initialize queue
queue = deque()
# Check if empty
if not queue:
print("Queue is empty")
else:
print("Queue is not empty")
26
# Size of queue
print("Size:", len(queue)) # Output: 2
# Initialize deque
dq = deque()
# Add/Append operations
dq.append(10) # Add item at Rear/Right end of queue
dq.appendleft(5) # Add item at Front/Left end
dq.append(20)
# Pop operations
dq.pop() # Removes 20 from rear/right
dq.popleft() # Removes 5 from front/left
# Check empty
print("Is empty?", not dq)
# Size: len(dqueue)
print("Size:", len(dq))
# Reverse()
dq.append(30)
dq.append(40)
dq.reverse() #Reverse the order of elements in-place
print("Reversed deque:", dq)
27
• Python Example (min-heap):
import heapq
heap = [5, 1, 9, 3]
heapq.heapify(heap) # Converts the list into a min-heap O(n)
print(heap) # Example output: [1, 3, 9, 5]
min_element = heapq.heappop(heap) # Removes and returns the smallest element and apply heapify
# O(log n)
import heapq
# Insert: O(log n)
heapq.heappush(heap, 2)
print("After push:", heap)
28
print("3 largest:", heapq.nlargest(3, nums)) #Get n largest elements (reverse min-heap)
8.8 Hashing
• Hashing uses a hash function to map keys to indices for constant time lookup
• Efficient search, insertion, deletion.
• All operations (Insert, Search, Delete) incur O(1) time
• Implemented in python using Dictionary, dict
8.9 Exercise
Q.1) You are given two sorted arrays nums1 and nums2. LeetCode 88
• nums1 has a length of m + n, where the first m elements are valid and the rest are empty (filled
with 0) for accommodating nums2.
• nums2 has exactly n elements.
29
Merge nums2 into nums1 in-place (without using any extra memory space) as a sorted array.
Q.2) Given a string containing only (),[], and{}, determine if the input string is valid (i.e, brackets are
closed in the correct order). Hint: Use stack LeetCode 20
Q.3) Find the first Unique Character in a String and return its index. Hint: Use Hashing (LeetCode 387)
8.9.1 Solution
References
[1] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. Introduction to Algo-
rithms. MIT Press, Cambridge, MA, 3rd edition, 2009.
[2] Steven Halim and Felix Halim. Competitive Programming 4: The Lower Bound of Programming Contests
in the 2020s, Book 1. CP4 Books, 1st edition, 2020. Released on July 19, 2020.
30