Algorithms and Problem Solving with Java
Linear Search and Binary Search
You are viewing a free preview lesson.
Lesson Overview
Searching programming-এর সবচেয়ে common operations-এর একটি।
Examples:
এই learner কি list-এ আছে?
এই course code কি পাওয়া গেছে?
এই score কি array-তে আছে?
এই ID কোন position-এ আছে?
Search করার অনেক strategy আছে।
এই lesson-এ আমরা দুইটি fundamental search algorithm শিখব:
Linear Search
Binary Search
Linear Search একে একে values check করে।
Binary Search sorted data ব্যবহার করে প্রতি step-এ search space-এর বড় একটি অংশ বাদ দেয়।
এই lesson-এ আমরা শিখব:
- What a search algorithm is
- Linear Search
- Returning boolean vs index
- Best and worst case
O(n)search- Binary Search
- Why sorted input is required
left,right, andmiddle- Implementing Binary Search
- Tracing Binary Search
O(log n)- Handling missing values
- Duplicate values
Arrays.binarySearch()Collections.binarySearch()- Linear Search vs Binary Search
- When sorting before searching makes sense
- Common search mistakes
What Is Searching?
Searching means trying to determine whether a target value exists in a collection of data।
Example:
int[] numbers = {
10,
20,
30,
40
};
Question:
Does 30 exist?
or:
At which index does 30 exist?
These are search problems।
Search Result Design
A search method can return different kinds of results depending on what the caller needs।
Boolean Search
If we only care whether the value exists:
static boolean contains(
int[] numbers,
int target
)
Result:
true
false
Index Search
If we care about position:
static int indexOf(
int[] numbers,
int target
)
Result:
0 or greater → found index
-1 → not found
Returning the Value Itself
For objects, a search might eventually return:
Course
Learner
Enrollment
or perhaps:
Optional<Course>
We'll study Optional later।
For now, arrays make boolean and index-based search easy to understand।
Linear Search
Linear Search checks values one by one।
Example:
[10, 20, 30, 40, 50]
Target = 40
Search process:
10 → no
20 → no
30 → no
40 → yes
Then stop।
Linear Search Implementation
static boolean contains(
int[] numbers,
int target
) {
for (
int number
: numbers
) {
if (
number == target
) {
return true;
}
}
return false;
}
Why Return Immediately?
Once the target is found:
return true;
There is no reason to inspect remaining values।
This is an early-return optimization and also makes the method easier to read।
Linear Search by Index
If we need the position:
static int indexOf(
int[] numbers,
int target
) {
for (
int i = 0;
i < numbers.length;
i++
) {
if (
numbers[i] == target
) {
return i;
}
}
return -1;
}
Why -1?
Valid indexes start from:
0
So:
-1
can safely represent:
Not found
Example
int[] numbers = {
10,
20,
30,
40
};
int index =
indexOf(
numbers,
30
);
System.out.println(
index
);
Output:
2
Linear Search Works on Unsorted Data
This is important।
Example:
int[] numbers = {
90,
10,
70,
30,
20
};
Linear Search works perfectly fine।
It does not require:
Sorted input
because it simply checks each value।
Linear Search Best Case
Suppose:
int[] numbers = {
42,
10,
20,
30
};
Target:
42
The first comparison succeeds।
Best case:
O(1)
Linear Search Worst Case
Suppose target is:
30
at the final position।
Or target does not exist at all।
Then every element may need to be checked।
Worst case:
O(n)
Linear Search Space Complexity
The iterative implementation uses only a few local variables।
Additional space:
O(1)
Searching Strings
Example:
static int indexOf(
String[] values,
String target
) {
for (
int i = 0;
i < values.length;
i++
) {
if (
values[i].equals(
target
)
) {
return i;
}
}
return -1;
}
Be Careful with null
If array values may contain null, this can fail:
values[i].equals(
target
);
because:
values[i]
might be null।
A safer comparison can use:
Objects.equals(
values[i],
target
);
with:
import java.util.Objects;
Example:
static int indexOf(
String[] values,
String target
) {
for (
int i = 0;
i < values.length;
i++
) {
if (
Objects.equals(
values[i],
target
)
) {
return i;
}
}
return -1;
}
Linear Search with Objects
Suppose:
record Course(
String code,
String title
) {
}
Search by code:
static int indexOfCourse(
Course[] courses,
String code
) {
for (
int i = 0;
i < courses.length;
i++
) {
if (
courses[i]
.code()
.equals(
code
)
) {
return i;
}
}
return -1;
}
The search criterion does not have to be the entire object।
You can search based on a specific field।
Searching Collections
With a List, Java already provides:
contains(...)
indexOf(...)
Example:
List<String> courses =
List.of(
"Java",
"Backend",
"System Design"
);
boolean found =
courses.contains(
"Backend"
);
For an ArrayList, this is generally a linear scan:
O(n)
Binary Search
Binary Search is much faster for repeated searching on sorted data।
Core requirement:
The data must be sorted.
Example:
[10, 20, 30, 40, 50, 60, 70]
Target:
60
Instead of checking from the beginning, Binary Search looks near the middle first।
Binary Search Intuition
Start:
[10, 20, 30, 40, 50, 60, 70]
Middle:
40
Target:
60
Since:
60 > 40
everything to the left of 40 can be ignored।
Remaining:
[50, 60, 70]
Middle:
60
Found।
Why Can We Ignore Half?
Because the data is sorted।
If:
target > middle value
then every value to the left is also too small।
If:
target < middle value
then every value to the right is too large।
That is what makes Binary Search possible।
Binary Search Cannot Reliably Work on Unsorted Data
Suppose:
[80, 10, 60, 20, 90]
Target:
90
If the middle is:
60
and we conclude:
90 > 60
there is no guarantee values on the left are smaller।
The ordering assumption is broken।
Therefore Binary Search requires sorted input।
Binary Search State
We maintain three important positions:
left
right
middle
Example:
int left =
0;
int right =
numbers.length - 1;
Then:
int middle =
left
+ (
right - left
) / 2;
Why This Middle Formula?
You may also see:
(left + right) / 2
For normal small arrays this often works।
But:
left + right
can theoretically overflow int for very large index values।
This version:
left
+ (
right - left
) / 2
avoids that problem।
It is a good habit।
Full Binary Search Implementation
static int binarySearch(
int[] sortedNumbers,
int target
) {
int left =
0;
int right =
sortedNumbers.length - 1;
while (
left <= right
) {
int middle =
left
+ (
right - left
) / 2;
int value =
sortedNumbers[middle];
if (
value == target
) {
return middle;
}
if (
value < target
) {
left =
middle + 1;
} else {
right =
middle - 1;
}
}
return -1;
}
Why left <= right?
The search is valid while there is at least one candidate position remaining।
If:
left == right
there is exactly one candidate left।
So it still needs to be checked।
When:
left > right
the search range is empty।
Trace Binary Search
Array:
[10, 20, 30, 40, 50, 60, 70]
Target:
60
Initial:
left = 0
right = 6
Middle:
3
Value:
40
Since:
60 > 40
set:
left = 4
Second Step
Search range:
index 4 to 6
Values:
50 60 70
Now:
left = 4
right = 6
middle = 5
Value:
60
Target found।
Return:
5
Trace Missing Value
Array:
[10, 20, 30, 40, 50]
Target:
35
Start:
left = 0
right = 4
middle = 2
value = 30
Since:
35 > 30
new:
left = 3
Next Step
left = 3
right = 4
middle = 3
value = 40
Since:
35 < 40
new:
right = 2
Now:
left = 3
right = 2
So:
left > right
Search ends।
Return:
-1
Binary Search Complexity
Each step removes approximately half the remaining candidates।
Example:
1,024 elements
↓
512
↓
256
↓
128
↓
64
↓
32
↓
16
↓
8
↓
4
↓
2
↓
1
Only around:
10 steps
Worst-case time complexity:
O(log n)
Binary Search Space Complexity
Our iterative implementation uses:
left
right
middle
value
No memory grows with input size।
Extra space:
O(1)
Recursive Binary Search
Binary Search can also be implemented recursively।
Example:
static int binarySearch(
int[] sortedNumbers,
int target
) {
return binarySearch(
sortedNumbers,
target,
0,
sortedNumbers.length - 1
);
}
static int binarySearch(
int[] sortedNumbers,
int target,
int left,
int right
) {
if (
left > right
) {
return -1;
}
int middle =
left
+ (
right - left
) / 2;
int value =
sortedNumbers[middle];
if (
value == target
) {
return middle;
}
if (
value < target
) {
return binarySearch(
sortedNumbers,
target,
middle + 1,
right
);
}
return binarySearch(
sortedNumbers,
target,
left,
middle - 1
);
}
Iterative vs Recursive Binary Search
Both have time:
O(log n)
But iterative version uses:
O(1)
extra space।
Recursive version uses call-stack space:
O(log n)
For Java production code, iterative Binary Search is often preferable unless recursion makes a specific implementation clearer।
Binary Search Best Case
If target is exactly at the first middle position:
O(1)
Example:
[10, 20, 30, 40, 50]
Target = 30
First comparison finds it।
Worst case remains:
O(log n)
Linear Search vs Binary Search
Linear Search
Requirements:
No sorting required
Worst time:
O(n)
Works naturally with unsorted data।
Binary Search
Requirements:
Sorted data
Worst time:
O(log n)
Much faster on large sorted datasets।
Comparison Example
Suppose:
1,000,000 values
Linear Search worst case:
around 1,000,000 comparisons
Binary Search:
around 20 comparisons
That is a huge difference।
But Sorting Also Has a Cost
Suppose your array is unsorted:
[50, 10, 90, 20, 70]
You could:
Sort
Then binary search
But sorting itself has a cost।
Efficient sorting is commonly around:
O(n log n)
Then one Binary Search:
O(log n)
Total:
O(n log n)
for the sort + one search।
One Search on Unsorted Data
If you need only one lookup:
Linear Search → O(n)
may be better than:
Sort + Binary Search
→ O(n log n)
because you avoid sorting entirely।
Many Searches
Suppose the data is stable and you perform:
10,000 searches
Then sorting once may be worthwhile।
Conceptually:
Sort once
+
many O(log n) searches
can outperform:
many O(n) linear searches
Search Strategy Depends on Context
Ask:
Is data already sorted?
How many searches will happen?
Does original order matter?
Will data change frequently?
Do I need exact index positions?
Could a HashMap or HashSet be better?
Binary Search is not automatically the best search strategy।
Hash-Based Lookup
If you only need membership checking:
Set<String> codes =
new HashSet<>();
then:
codes.contains(
target
);
is typically average:
O(1)
This can be even more suitable than Binary Search when:
Ordering is not required
Fast membership lookup matters
Additional memory is acceptable
Search by Key
Suppose you have:
CourseCode → Course
A Map<CourseCode, Course> may be more appropriate than repeatedly searching an array or list।
Example:
Map<String, String> courses =
new HashMap<>();
courses.put(
"JAVA",
"Java Foundation"
);
Lookup:
courses.get(
"JAVA"
);
Typical expected lookup:
O(1)
Again:
Choose the data structure based on access pattern.
Arrays.binarySearch()
Java provides Binary Search in:
java.util.Arrays
Example:
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] numbers = {
10,
20,
30,
40,
50
};
int index =
Arrays.binarySearch(
numbers,
30
);
System.out.println(
index
);
}
}
Output:
2
Found Result
When found:
result >= 0
and represents an index where the matching value was found।
Missing Result
When missing:
result < 0
The exact negative result encodes an insertion point।
For basic usage:
boolean found =
Arrays.binarySearch(
numbers,
target
) >= 0;
is enough।
Understanding the Insertion Point
Suppose:
int[] numbers = {
10,
20,
40,
50
};
Search:
30
If inserted while preserving order, 30 belongs at index:
2
Arrays.binarySearch() returns a negative value encoding that insertion point using:
-(insertionPoint) - 1
So for insertion point 2:
-3
Recovering the Insertion Point
If:
int result =
Arrays.binarySearch(
numbers,
target
);
and:
result < 0
then:
int insertionPoint =
-result - 1;
Example
int[] numbers = {
10,
20,
40,
50
};
int result =
Arrays.binarySearch(
numbers,
30
);
System.out.println(
result
);
int insertionPoint =
-result - 1;
System.out.println(
insertionPoint
);
Output conceptually:
-3
2
Do You Need to Memorize This?
Not necessarily for everyday usage।
But it is useful to understand why a missing result is not always:
-1
Arrays.binarySearch() Still Requires Sorted Input
This is critical।
Incorrect:
int[] numbers = {
50,
10,
30
};
Arrays.binarySearch(
numbers,
30
);
Do not expect meaningful behavior from unsorted input।
Correct:
Arrays.sort(
numbers
);
int index =
Arrays.binarySearch(
numbers,
30
);
Collections.binarySearch()
For sorted List data, Java provides:
Collections.binarySearch(...)
Example:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers =
new ArrayList<>(
List.of(
10,
20,
30,
40,
50
)
);
int index =
Collections.binarySearch(
numbers,
30
);
System.out.println(
index
);
}
}
Output:
2
Collections.binarySearch() Requirement
The list must be sorted according to the same ordering used by the search।
For natural ordering:
Collections.sort(
numbers
);
then:
Collections.binarySearch(
numbers,
target
);
Binary Search and Custom Ordering
Later, when we learn Comparator, we may sort objects using custom ordering।
If a list is sorted using a comparator, Binary Search must use a compatible comparator।
Example conceptually:
Collections.binarySearch(
courses,
target,
comparator
);
Sorting and searching must agree on the same ordering rule।
Duplicate Values
Suppose:
[10, 20, 20, 20, 30]
Search target:
20
Binary Search may return an index containing 20, but it is not necessarily guaranteed to be the first or last occurrence unless the API/algorithm is specifically designed for that।
Example
Possible result:
1
2
or
3
depending on implementation and search path।
If you need:
First occurrence
or:
Last occurrence
you need a modified Binary Search।
Find First Occurrence
Conceptually, when a match is found:
Record the index
Continue searching left
Example:
static int firstIndexOf(
int[] sortedNumbers,
int target
) {
int left =
0;
int right =
sortedNumbers.length - 1;
int result =
-1;
while (
left <= right
) {
int middle =
left
+ (
right - left
) / 2;
if (
sortedNumbers[middle]
== target
) {
result =
middle;
right =
middle - 1;
} else if (
sortedNumbers[middle]
< target
) {
left =
middle + 1;
} else {
right =
middle - 1;
}
}
return result;
}
Find Last Occurrence
When a match is found:
Record the index
Continue searching right
Example:
static int lastIndexOf(
int[] sortedNumbers,
int target
) {
int left =
0;
int right =
sortedNumbers.length - 1;
int result =
-1;
while (
left <= right
) {
int middle =
left
+ (
right - left
) / 2;
if (
sortedNumbers[middle]
== target
) {
result =
middle;
left =
middle + 1;
} else if (
sortedNumbers[middle]
< target
) {
left =
middle + 1;
} else {
right =
middle - 1;
}
}
return result;
}
These are good examples of adapting an algorithm to specific requirements।
Binary Search Is More Than Exact Lookup
The same idea can solve problems such as:
Find first value >= target
Find last value <= target
Find insertion position
Find boundary between false and true conditions
These are sometimes called:
Binary search on boundaries
We won't go deeply into advanced variations here, but it is useful to know Binary Search is broader than exact-value lookup।
Search and Sorted Strings
Example:
String[] names = {
"Jalisa",
"Nur",
"Sakib",
"Subu",
"Sumu"
};
Because the array is sorted according to String natural ordering:
int index =
Arrays.binarySearch(
names,
"Subu"
);
can be used।
Sorting First
If input is:
String[] names = {
"Sumu",
"Sakib",
"Nur",
"Subu",
"Jalisa"
};
then:
Arrays.sort(
names
);
before:
Arrays.binarySearch(
names,
"Subu"
);
Sorting Mutates the Array
Remember:
Arrays.sort(
names
);
changes the original order।
If original order matters:
String[] sorted =
Arrays.copyOf(
names,
names.length
);
Arrays.sort(
sorted
);
Then search:
Arrays.binarySearch(
sorted,
target
);
Index Meaning After Sorting
This is subtle।
Suppose original:
Index 0 → Sumu
Index 1 → Sakib
Index 2 → Nur
After sorting:
Index 0 → Nur
Index 1 → Sakib
Index 2 → Sumu
Binary Search returns the index in the sorted array, not the original array।
If original position matters, sorting a copy and searching it does not directly answer:
Where was this item originally?
Search Requirements Matter
Always define the question precisely।
Do you need:
Existence?
Current sorted position?
Original position?
First occurrence?
Last occurrence?
Associated object?
Fast repeated lookup?
Different requirements can lead to different data structures and algorithms।
Common Mistake 1 — Binary Search on Unsorted Data
Wrong:
binarySearch(
unsorted,
target
);
Binary Search fundamentally depends on ordering।
Common Mistake 2 — Moving the Wrong Boundary
Suppose:
middle value < target
Then the target, if present, must be to the right।
Correct:
left =
middle + 1;
Not:
right =
middle - 1;
Common Mistake 3 — Forgetting +1 or -1
Bad:
left =
middle;
or:
right =
middle;
can cause the same middle index to be reconsidered repeatedly and may create an infinite loop।
Correct movement removes the already-checked position:
left =
middle + 1;
or:
right =
middle - 1;
Common Mistake 4 — Using < Instead of <=
This:
while (
left < right
)
can skip the final single candidate in a standard exact Binary Search implementation if the rest of the logic is not adjusted accordingly।
The straightforward implementation uses:
while (
left <= right
)
Common Mistake 5 — Sorting for One Search
If data is unsorted and you need one target lookup, sorting everything just to perform Binary Search may be more expensive than a simple linear scan।
Common Mistake 6 — Forgetting Sort Mutation
Arrays.sort(
values
);
changes ordering।
If the original sequence carries meaning, preserve it।
Common Mistake 7 — Assuming Missing binarySearch() Result Is -1
Use:
result < 0
to detect absence।
The exact negative value may encode insertion position।
Common Mistake 8 — Assuming Duplicate Search Returns First Match
A normal Binary Search only promises a matching position, not necessarily the earliest duplicate।
Common Mistake 9 — Using Binary Search When Hash Lookup Fits Better
If your only requirement is frequent membership lookup and order is irrelevant:
HashSet
may be a better design।
Common Mistake 10 — Optimizing Without Considering Data Changes
Suppose you maintain a sorted array for Binary Search, but new values are constantly inserted।
Keeping an array sorted can itself be expensive।
Search cost is only one part of the data structure's lifecycle।
Practical Example — Course Code Search
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
String[] courseCodes = {
"ALGORITHMS",
"BACKEND",
"JAVA",
"SYSTEM-DESIGN"
};
String target =
"JAVA";
int index =
Arrays.binarySearch(
courseCodes,
target
);
if (
index >= 0
) {
System.out.println(
target
+ " found at index "
+ index
);
} else {
System.out.println(
target
+ " not found"
);
}
}
}
Practical Example — Linear Search Over Learners
record Learner(
long id,
String name
) {
}
Search:
static Learner findById(
Learner[] learners,
long id
) {
for (
Learner learner
: learners
) {
if (
learner.id()
== id
) {
return learner;
}
}
return null;
}
This is:
O(n)
For a very small in-memory array this may be perfectly reasonable।
For a large frequently queried dataset, a map keyed by ID may be a better structure।
Practical Example — Choose the Search Strategy
Scenario 1
You have:
20 values
Unsorted.
One search.
Good default:
Linear Search
Scenario 2
You have:
5 million sorted values
Many repeated searches.
Good candidate:
Binary Search
Scenario 3
You have:
Millions of IDs
Frequent membership checks.
Order irrelevant.
Good candidate:
HashSet
Scenario 4
You need:
ID → object lookup
Good candidate:
HashMap
Practice 1 — Linear Search
Implement:
static boolean contains(
int[] numbers,
int target
)
Solution
static boolean contains(
int[] numbers,
int target
) {
for (
int number
: numbers
) {
if (
number == target
) {
return true;
}
}
return false;
}
Practice 2 — Index Search
Implement:
static int indexOf(
String[] values,
String target
)
Return -1 when missing।
Solution
static int indexOf(
String[] values,
String target
) {
for (
int i = 0;
i < values.length;
i++
) {
if (
values[i].equals(
target
)
) {
return i;
}
}
return -1;
}
Practice 3 — Binary Search
Implement:
static int binarySearch(
int[] sorted,
int target
)
Solution
static int binarySearch(
int[] sorted,
int target
) {
int left =
0;
int right =
sorted.length - 1;
while (
left <= right
) {
int middle =
left
+ (
right - left
) / 2;
if (
sorted[middle]
== target
) {
return middle;
}
if (
sorted[middle]
< target
) {
left =
middle + 1;
} else {
right =
middle - 1;
}
}
return -1;
}
Practice 4 — Trace Binary Search
Array:
[10, 20, 30, 40, 50, 60, 70]
Target:
20
First middle:
index 3 → 40
Since:
20 < 40
new range becomes:
index 0 to 2
Next middle:
index 1 → 20
Found।
Practice 5 — Complexity
Linear Search worst case?
Answer
O(n)
Practice 6 — Complexity
Binary Search worst case?
Answer
O(log n)
Practice 7 — Requirement
Can Binary Search correctly operate on arbitrary unsorted input?
Answer
No।
The algorithm depends on sorted ordering to eliminate half of the remaining candidates।
Practice 8 — Arrays.binarySearch()
Given:
int[] numbers = {
10,
20,
30,
40
};
write a membership check for 30।
Solution
boolean found =
Arrays.binarySearch(
numbers,
30
) >= 0;
Practice 9 — Missing Result
Given:
int[] numbers = {
10,
20,
40,
50
};
search for 30।
Insertion point is:
2
What encoded result does Arrays.binarySearch() use?
Answer
Formula:
-(insertionPoint) - 1
So:
-2 - 1
= -3
Practice 10 — One Search
You have an unsorted array of one million elements and need exactly one search।
Which is more directly appropriate?
Sort + Binary Search
or
Linear Search
Answer
Usually:
Linear Search
because sorting first costs more than simply scanning once।
Practice 11 — Many Searches
You have a stable sorted dataset of one million elements and expect many thousands of searches।
Which is a strong choice?
Answer
Binary Search
because each lookup is:
O(log n)
Practice 12 — Frequent Membership
Ordering does not matter and you have frequent lookups by exact value।
What structure may be better than both array search strategies?
Answer
Often:
HashSet
with typical average membership lookup:
O(1)
True or False
- Linear Search requires sorted input.
- Linear Search worst-case time is
O(n). - Binary Search requires ordered data.
- Binary Search repeatedly reduces the search range.
- Binary Search worst-case time is
O(log n). left <= rightallows checking a final single candidate.- When middle value is less than the target, search should continue on the left.
Arrays.binarySearch()returns a negative value when the target is missing.- A missing Binary Search result is always exactly
-1. - Sorting before one search is always better than Linear Search.
- Binary Search can return any matching occurrence when duplicates exist.
- Hash-based lookup may be more appropriate when ordering is irrelevant and membership checks are frequent.
Answers
1. False
2. True
3. True
4. True
5. True
6. True
7. False
8. True
9. False
10. False
11. True
12. True
Knowledge Check
Question 1
How does Linear Search work?
Question 2
What is Linear Search's worst-case complexity?
Question 3
Why does Binary Search require sorted data?
Question 4
What do left and right represent?
Question 5
How is the middle index calculated safely?
Question 6
What happens when the middle value is smaller than the target?
Question 7
Why does Binary Search have O(log n) complexity?
Question 8
What does a negative Arrays.binarySearch() result mean?
Question 9
When is Linear Search often preferable to sorting and then using Binary Search?
Question 10
When does Binary Search become particularly useful?
Question 11
Why might a HashSet be better for some search requirements?
Question 12
What happens with duplicate values in a normal Binary Search?
Knowledge Check Answers
Answer 1
Linear Search checks elements sequentially until the target is found or there are no elements left।
Answer 2
O(n)
Answer 3
Sorted ordering allows the algorithm to determine that an entire half of the remaining values cannot contain the target।
Answer 4
They represent the current inclusive search boundaries।
Answer 5
int middle =
left
+ (
right - left
) / 2;
Answer 6
The target, if present, must be on the right side, so:
left =
middle + 1;
Answer 7
Because every iteration discards roughly half of the remaining search space।
Answer 8
The target was not found. The negative value also encodes the insertion point that would preserve sorted order।
Answer 9
When the input is unsorted and only one or a small number of searches are required।
Answer 10
When the data is already sorted or can remain sorted and many searches need to be performed efficiently।
Answer 11
A HashSet offers typical average O(1) membership checks and does not require sorted ordering, at the cost of additional memory and different ordering semantics।
Answer 12
It can return a matching index, but a normal Binary Search does not necessarily guarantee the first or last matching occurrence।
Search Strategy Checklist
Before choosing a search algorithm, ask:
Is the data sorted?
Does original order matter?
How many searches will happen?
How often does the data change?
Do I need the index?
Do I need the first duplicate?
Do I only need existence?
Would a Set solve the problem better?
Would a Map keyed by ID be more appropriate?
Do not choose Binary Search simply because:
O(log n) sounds faster.
The surrounding data lifecycle matters।
Search Strategy Summary
Linear Search
Sorted data required?
No
Worst-case time:
O(n)
Extra space:
O(1)
Good for:
Small data
Unsorted data
One-off searches
Simple sequential lookup
Binary Search
Sorted data required?
Yes
Worst-case time:
O(log n)
Extra space:
O(1) iterative
Good for:
Large sorted data
Repeated searches
Ordered datasets
Boundary lookup problems
Hash-Based Search
Sorted data required?
No
Typical membership:
Average O(1)
Extra space:
O(n)
Good for:
Frequent exact membership lookup
Key-based lookup
When ordering is not the main requirement
Lesson Summary
এই lesson-এ আমরা two fundamental search strategies শিখেছি।
We learned:
- Search can return existence, position, or a matching object
- Linear Search checks values sequentially
- Linear Search works with unsorted data
- Linear Search worst-case time is
O(n) - Binary Search requires sorted data
- Binary Search uses
left,right, andmiddle - Each Binary Search step discards roughly half the search space
- Iterative Binary Search has
O(log n)time andO(1)extra space - Recursive Binary Search uses
O(log n)call-stack space Arrays.binarySearch()provides standard array Binary SearchCollections.binarySearch()provides Binary Search for sorted lists- Missing standard-library Binary Search results are negative and encode insertion position
- Duplicate values require modified logic when first or last occurrence matters
- Sorting before a single search is often unnecessary
- Sorting once may make sense for many repeated searches
- Sorting changes array order unless a copy is made
- A HashSet or HashMap may be a better choice for frequent exact lookup
- Search algorithm selection depends on the whole data-access pattern, not Big-O alone
The central comparison is:
Linear Search
→ inspect values one by one
→ O(n)
Binary Search
→ discard half repeatedly
→ O(log n)
→ requires sorted data
And the engineering question is not simply:
Which algorithm is theoretically faster?
It is:
Which data structure and search strategy
fit this application's access pattern?
Next Lesson
পরবর্তী lesson:
Simple Sorting Algorithms
আমরা শিখব:
- What sorting means
- Why sorted data is useful
- Comparison and swapping
- Bubble Sort
- Selection Sort
- Insertion Sort
- Step-by-step execution
O(n²)complexity- Best and worst-case behavior
- In-place sorting
- Stability intuition
- Why these algorithms matter even though Java provides
Arrays.sort()