140 lines
3.6 KiB
Markdown
140 lines
3.6 KiB
Markdown
# 01: Array Basics
|
|
|
|
## Overview
|
|
Array basics are the foundation of algorithmic thinking. Understanding how to traverse, manipulate, and analyze arrays is crucial for solving more complex problems.
|
|
|
|
## Key Concepts
|
|
|
|
### 1. Array Traversal
|
|
**What it is**: Visiting each element in an array in sequence
|
|
|
|
**Example**:
|
|
```typescript
|
|
// Linear traversal
|
|
function linearSearch(arr: number[], target: number): number {
|
|
for (let i = 0; i < arr.length; i++) {
|
|
if (arr[i] === target) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1; // Not found
|
|
}
|
|
```
|
|
|
|
**Important considerations**:
|
|
- Always check if array is empty first
|
|
- Use `for` loops for precise index control
|
|
- Use `forEach` or `map` when you need the value but not the index
|
|
|
|
### 2. Basic Array Operations
|
|
|
|
#### Finding Minimum and Maximum
|
|
```typescript
|
|
function findMinMax(arr: number[]): { min: number, max: number } {
|
|
if (arr.length === 0) {
|
|
throw new Error("Array is empty");
|
|
}
|
|
|
|
let min = arr[0];
|
|
let max = arr[0];
|
|
|
|
for (let i = 1; i < arr.length; i++) {
|
|
if (arr[i] < min) {
|
|
min = arr[i];
|
|
}
|
|
if (arr[i] > max) {
|
|
max = arr[i];
|
|
}
|
|
}
|
|
|
|
return { min, max };
|
|
}
|
|
```
|
|
|
|
**Time Complexity**: O(n) - We visit each element once
|
|
**Space Complexity**: O(1) - We only store a few variables
|
|
|
|
#### Frequency Counting
|
|
```typescript
|
|
function frequencyCount(arr: number[]): Map<number, number> {
|
|
const frequency = new Map<number, number>();
|
|
|
|
for (const num of arr) {
|
|
frequency.set(num, (frequency.get(num) || 0) + 1);
|
|
}
|
|
|
|
return frequency;
|
|
}
|
|
```
|
|
|
|
**Time Complexity**: O(n) - One pass through the array
|
|
**Space Complexity**: O(n) - Store frequency of each unique element
|
|
|
|
### 3. Edge Cases to Consider
|
|
|
|
1. **Empty array**: What happens when `arr.length === 0`?
|
|
2. **Single element**: Arrays with only one element
|
|
3. **All same elements**: Arrays where all values are identical
|
|
4. **Negative numbers**: How algorithms handle negative values
|
|
5. **Large arrays**: Performance considerations
|
|
|
|
## Practice Patterns
|
|
|
|
### Pattern 1: Linear Search Variations
|
|
**Problem**: Find all occurrences of a target
|
|
```typescript
|
|
function findAllOccurrences(arr: number[], target: number): number[] {
|
|
const indices: number[] = [];
|
|
|
|
for (let i = 0; i < arr.length; i++) {
|
|
if (arr[i] === target) {
|
|
indices.push(i);
|
|
}
|
|
}
|
|
|
|
return indices;
|
|
}
|
|
```
|
|
|
|
**Time Complexity**: O(n)
|
|
**Space Complexity**: O(k) where k is number of occurrences
|
|
|
|
### Pattern 2: Array Validation
|
|
**Problem**: Check if array meets certain criteria
|
|
```typescript
|
|
function isNonDecreasing(arr: number[]): boolean {
|
|
for (let i = 1; i < arr.length; i++) {
|
|
if (arr[i] < arr[i-1]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
```
|
|
|
|
**Time Complexity**: O(n)
|
|
**Space Complexity**: O(1)
|
|
|
|
## Real-world Applications
|
|
|
|
1. **Search functionality**: Finding items in a list
|
|
2. **Data analysis**: Counting frequencies, finding trends
|
|
3. **Game development**: Player positions, inventory management
|
|
4. **Web development**: Form validation, data filtering
|
|
|
|
## Common Mistakes
|
|
|
|
1. **Off-by-one errors**: Using `<` vs `<=` in loops
|
|
2. **Undefined access**: Not checking array bounds
|
|
3. **Memory leaks**: Not clearing temporary arrays
|
|
4. **Inefficient algorithms**: Using nested loops when unnecessary
|
|
|
|
## Next Steps
|
|
|
|
After mastering array basics, you should be comfortable with:
|
|
- Traversing arrays in different ways
|
|
- Performing basic operations (search, count, min/max)
|
|
- Handling edge cases properly
|
|
- Understanding time complexity of basic operations
|
|
|
|
**Ready for**: Two pointers technique (next topic) |