@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
icon: material/timer-sand
|
||||||
|
---
|
||||||
|
|
||||||
|
# 第 2 章 Complexity Analysis
|
||||||
|
|
||||||
|
<div class="center-table" markdown>
|
||||||
|
|
||||||
|
![complexity_analysis](../assets/covers/chapter_complexity_analysis.jpg){ width="600" }{ class="cover-image" }
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
!!! abstract
|
||||||
|
|
||||||
|
Complexity analysis is like a space-time guide in the vast universe of algorithms.
|
||||||
|
|
||||||
|
It leads us to explore deeply in the dimensions of time and space, in search of more elegant solutions.
|
||||||
|
|
||||||
|
## 本章内容
|
||||||
|
|
||||||
|
- [2.1 Evaluating Algorithm Efficiency](https://www.hello-algo.com/chapter_computational_complexity/performance_evaluation/)
|
||||||
|
- [2.2 Iteration and Recursion](https://www.hello-algo.com/chapter_computational_complexity/iteration_and_recursion/)
|
||||||
|
- [2.3 Time Complexity](https://www.hello-algo.com/chapter_computational_complexity/time_complexity/)
|
||||||
|
- [2.4 Space Complexity](https://www.hello-algo.com/chapter_computational_complexity/space_complexity/)
|
||||||
|
- [2.5 Summary](https://www.hello-algo.com/chapter_computational_complexity/summary/)
|
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 2.1 Evaluation Of Algorithm Efficiency
|
||||||
|
|
||||||
|
In algorithm design, we aim to achieve two goals in succession:
|
||||||
|
|
||||||
|
1. **Finding a Solution to the Problem**: The algorithm needs to reliably find the correct solution within the specified input range.
|
||||||
|
2. **Seeking the Optimal Solution**: There may be multiple ways to solve the same problem, and our goal is to find the most efficient algorithm possible.
|
||||||
|
|
||||||
|
In other words, once the ability to solve the problem is established, the efficiency of the algorithm emerges as the main benchmark for assessing its quality, which includes the following two aspects.
|
||||||
|
|
||||||
|
- **Time Efficiency**: The speed at which an algorithm runs.
|
||||||
|
- **Space Efficiency**: The amount of memory space the algorithm consumes.
|
||||||
|
|
||||||
|
In short, our goal is to design data structures and algorithms that are both "fast and economical". Effectively evaluating algorithm efficiency is crucial, as it allows for the comparison of different algorithms and guides the design and optimization process.
|
||||||
|
|
||||||
|
There are mainly two approaches for assessing efficiency: practical testing and theoretical estimation.
|
||||||
|
|
||||||
|
## 2.1.1 Practical Testing
|
||||||
|
|
||||||
|
Let's consider a scenario where we have two algorithms, `A` and `B`, both capable of solving the same problem. To compare their efficiency, the most direct method is to use a computer to run both algorithms while monitoring and recording their execution time and memory usage. This approach provides a realistic assessment of their performance, but it also has significant limitations.
|
||||||
|
|
||||||
|
On one hand, it's challenging to eliminate the interference of the test environment. Hardware configurations can significantly affect the performance of algorithms. For instance, on one computer, Algorithm `A` might run faster than Algorithm `B`, but the results could be the opposite on another computer with different specifications. This means we would need to conduct tests on a variety of machines and calculate an average efficiency, which is impractical.
|
||||||
|
|
||||||
|
Furthermore, conducting comprehensive tests is resource-intensive. The efficiency of algorithms can vary with different volumes of input data. For example, with smaller data sets, Algorithm A might run faster than Algorithm B; however, this could change with larger data sets. Therefore, to reach a convincing conclusion, it's necessary to test a range of data sizes, which requires excessive computational resources.
|
||||||
|
|
||||||
|
## 2.1.2 Theoretical Estimation
|
||||||
|
|
||||||
|
Given the significant limitations of practical testing, we can consider assessing algorithm efficiency solely through calculations. This method of estimation is known as 'asymptotic complexity analysis,' often simply referred to as 'complexity analysis.
|
||||||
|
|
||||||
|
Complexity analysis illustrates the relationship between the time (and space) resources required by an algorithm and the size of its input data. **It describes the growing trend in the time and space required for the execution of an algorithm as the size of the input data increases**. This definition might sound a bit complex, so let's break it down into three key points for easier understanding.
|
||||||
|
|
||||||
|
- In complexity analysis, 'time and space' directly relate to 'time complexity' and 'space complexity,' respectively.
|
||||||
|
- The statement "as the size of the input data increases" highlights that complexity analysis examines the interplay between the size of the input data and the algorithm's efficiency.
|
||||||
|
- Lastly, the phrase "the growing trend in time and space required" emphasizes that the focus of complexity analysis is not on the specific values of running time or space occupied, but on the rate at which these requirements increase with larger input sizes.
|
||||||
|
|
||||||
|
**Complexity analysis overcomes the drawbacks of practical testing methods in two key ways:**.
|
||||||
|
|
||||||
|
- It is independent of the testing environment, meaning the analysis results are applicable across all operating platforms.
|
||||||
|
- It effectively demonstrates the efficiency of algorithms with varying data volumes, particularly highlighting performance in large-scale data scenarios.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
If you're still finding the concept of complexity confusing, don't worry. We will cover it in more detail in the subsequent chapters.
|
||||||
|
|
||||||
|
Complexity analysis provides us with a 'ruler' for evaluating the efficiency of algorithms, enabling us to measure the time and space resources required to execute a given algorithm and to compare the efficiency of different algorithms.
|
||||||
|
|
||||||
|
Complexity is a mathematical concept that might seem abstract and somewhat challenging for beginners. From this perspective, introducing complexity analysis at the very beginning may not be the most suitable approach. However, when discussing the characteristics of a particular data structure or algorithm, analyzing its operational speed and space usage is often inevitable.
|
||||||
|
|
||||||
|
Therefore, it is recommended that before diving deeply into data structures and algorithms, **one should first gain a basic understanding of complexity analysis. This foundational knowledge will facilitate the complexity analysis of simple algorithms.**
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 2.5 Summary
|
||||||
|
|
||||||
|
### 1. Highlights
|
||||||
|
|
||||||
|
**Evaluation of Algorithm Efficiency**
|
||||||
|
|
||||||
|
- Time and space efficiency are the two leading evaluation indicators to measure an algorithm.
|
||||||
|
- We can evaluate the efficiency of an algorithm through real-world testing. Still, it isn't easy to eliminate the side effects from the testing environment, and it consumes a lot of computational resources.
|
||||||
|
- Complexity analysis overcomes the drawbacks of real-world testing. The analysis results can apply to all operating platforms and reveal the algorithm's efficiency under variant data scales.
|
||||||
|
|
||||||
|
**Time Complexity**
|
||||||
|
|
||||||
|
- Time complexity is used to measure the trend of algorithm running time as the data size grows., which can effectively evaluate the algorithm's efficiency. However, it may fail in some cases, such as when the input volume is small or the time complexities are similar, making it difficult to precisely compare the efficiency of algorithms.
|
||||||
|
- The worst time complexity is denoted by big $O$ notation, which corresponds to the asymptotic upper bound of the function, reflecting the growth rate in the number of operations $T(n)$ as $n$ tends to positive infinity.
|
||||||
|
- The estimation of time complexity involves two steps: first, counting the number of operations, and then determining the asymptotic upper bound.
|
||||||
|
- Common time complexities, from lowest to highest, are $O(1)$, $O(\log n)$, $O(n)$, $O(n \log n)$, $O(n^2)$, $O(2^n)$, and $O(n!)$.
|
||||||
|
- The time complexity of certain algorithms is not fixed and depends on the distribution of the input data. The time complexity can be categorized into worst-case, best-case, and average. The best-case time complexity is rarely used because the input data must meet strict conditions to achieve the best-case.
|
||||||
|
- The average time complexity reflects the efficiency of an algorithm with random data inputs, which is closest to the performance of algorithms in real-world scenarios. Calculating the average time complexity requires statistical analysis of input data and a synthesized mathematical expectation.
|
||||||
|
|
||||||
|
**Space Complexity**
|
||||||
|
|
||||||
|
- Space complexity serves a similar purpose to time complexity and is used to measure the trend of space occupied by an algorithm as the data volume increases.
|
||||||
|
- The memory space associated with the operation of an algorithm can be categorized into input space, temporary space, and output space. Normally, the input space is not considered when determining space complexity. The temporary space can be classified into instruction space, data space, and stack frame space, and the stack frame space usually only affects the space complexity for recursion functions.
|
||||||
|
- We mainly focus on the worst-case space complexity, which refers to the measurement of an algorithm's space usage when given the worst-case input data and during the worst-case execution scenario.
|
||||||
|
- Common space complexities are $O(1)$, $O(\log n)$, $O(n)$, $O(n^2)$ and $O(2^n)$ from lowest to highest.
|
||||||
|
|
||||||
|
### 2. Q & A
|
||||||
|
|
||||||
|
!!! question "Is the space complexity of tail recursion $O(1)$?"
|
||||||
|
|
||||||
|
Theoretically, the space complexity of a tail recursion function can be optimized to $O(1)$. However, most programming languages (e.g., Java, Python, C++, Go, C#, etc.) do not support auto-optimization for tail recursion, so the space complexity is usually considered as $O(n)$.
|
||||||
|
|
||||||
|
!!! question "What is the difference between the terms function and method?"
|
||||||
|
|
||||||
|
A *function* can be executed independently, and all arguments are passed explicitly. A *method* is associated with an object and is implicitly passed to the object that calls it, allowing it to operate on the data contained within an instance of a class.
|
||||||
|
|
||||||
|
Let's illustrate with a few common programming languages.
|
||||||
|
|
||||||
|
- C is a procedural programming language without object-oriented concepts, so it has only functions. However, we can simulate object-oriented programming by creating structures (struct), and the functions associated with structures are equivalent to methods in other languages.
|
||||||
|
- Java and C# are object-oriented programming languages, and blocks of code (methods) are typically part of a class. Static methods behave like a function because it is bound to the class and cannot access specific instance variables.
|
||||||
|
- Both C++ and Python support both procedural programming (functions) and object-oriented programming (methods).
|
||||||
|
|
||||||
|
!!! question "Does the figure "Common Types of Space Complexity" reflect the absolute size of the occupied space?"
|
||||||
|
|
||||||
|
No, that figure shows the space complexity, which reflects the growth trend, not the absolute size of the space occupied.
|
||||||
|
|
||||||
|
For example, if you take $n = 8$ , the values of each curve do not align with the function because each curve contains a constant term used to compress the range of values to a visually comfortable range.
|
||||||
|
|
||||||
|
In practice, since we usually don't know each method's "constant term" complexity, it is generally impossible to choose the optimal solution for $n = 8$ based on complexity alone. But it's easier to choose for $n = 8^5$ as the growth trend is already dominant.
|
@ -0,0 +1,49 @@
|
|||||||
|
# Classification Of Data Structures
|
||||||
|
|
||||||
|
Common data structures include arrays, linked lists, stacks, queues, hash tables, trees, heaps, and graphs. They can be divided into two categories: logical structure and physical structure.
|
||||||
|
|
||||||
|
## Logical Structures: Linear And Non-linear
|
||||||
|
|
||||||
|
**Logical structures reveal logical relationships between data elements**. In arrays and linked lists, data are arranged in sequential order, reflecting the linear relationship between data; while in trees, data are arranged hierarchically from the top down, showing the derived relationship between ancestors and descendants; and graphs are composed of nodes and edges, reflecting the complex network relationship.
|
||||||
|
|
||||||
|
As shown in the figure below, logical structures can further be divided into "linear data structure" and "non-linear data structure". Linear data structures are more intuitive, meaning that the data are arranged linearly in terms of logical relationships; non-linear data structures, on the other hand, are arranged non-linearly.
|
||||||
|
|
||||||
|
- **Linear data structures**: arrays, linked lists, stacks, queues, hash tables.
|
||||||
|
- **Nonlinear data structures**: trees, heaps, graphs, hash tables.
|
||||||
|
|
||||||
|
![Linear and nonlinear data structures](classification_of_data_structure.assets/classification_logic_structure.png)
|
||||||
|
|
||||||
|
Non-linear data structures can be further divided into tree and graph structures.
|
||||||
|
|
||||||
|
- **Linear structures**: arrays, linked lists, queues, stacks, hash tables, with one-to-one sequential relationship between elements.
|
||||||
|
- **Tree structure**: tree, heap, hash table, with one-to-many relationship between elements.
|
||||||
|
- **Graph**: graph with many-to-many relationship between elements.
|
||||||
|
|
||||||
|
## Physical Structure: Continuous vs. Dispersed
|
||||||
|
|
||||||
|
**When an algorithm is running, the data being processed is stored in memory**. The figure below shows a computer memory module where each black square represents a memory space. We can think of the memory as a giant Excel sheet in which each cell can store data of a certain size.
|
||||||
|
|
||||||
|
**The system accesses the data at the target location by means of a memory address**. As shown in the figure below, the computer assigns a unique identifier to each cell in the table according to specific rules, ensuring that each memory space has a unique memory address. With these addresses, the program can access the data in memory.
|
||||||
|
|
||||||
|
![memory_strip, memory_space, memory_address](classification_of_data_structure.assets/computer_memory_location.png)
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
It is worth noting that comparing memory to the Excel sheet is a simplified analogy. The actual memory working mechanism is more complicated, involving the concepts of address, space, memory management, cache mechanism, virtual and physical memory.
|
||||||
|
|
||||||
|
Memory is a shared resource for all programs, and when a block of memory is occupied by one program, it cannot be used by other programs at the same time. **Therefore, considering memory resources is crucial in designing data structures and algorithms**. For example, the algorithm's peak memory usage should not exceed the remaining free memory of the system; if there is a lack of contiguous memory blocks, then the data structure chosen must be able to be stored in non-contiguous memory blocks.
|
||||||
|
|
||||||
|
As shown in the figure below, **Physical structure reflects the way data is stored in computer memory and it can be divided into consecutive space storage (arrays) and distributed space storage (linked lists)**. The physical structure determines how data is accessed, updated, added, deleted, etc. Logical and physical structure complement each other in terms of time efficiency and space efficiency.
|
||||||
|
|
||||||
|
![continuous vs. decentralized spatial storage](classification_of_data_structure.assets/classification_phisical_structure.png)
|
||||||
|
|
||||||
|
**It is worth stating that all data structures are implemented based on arrays, linked lists, or a combination of the two**. For example, stacks and queues can be implemented using both arrays and linked lists; and implementations of hash tables may contain both arrays and linked lists.
|
||||||
|
|
||||||
|
- **Array-based structures**: stacks, queues, hash tables, trees, heaps, graphs, matrices, tensors (arrays of dimension $\geq 3$), and so on.
|
||||||
|
- **Linked list-based structures**: stacks, queues, hash tables, trees, heaps, graphs, etc.
|
||||||
|
|
||||||
|
Data structures based on arrays are also known as "static data structures", which means that such structures' length remains constant after initialization. In contrast, data structures based on linked lists are called "dynamic data structures", meaning that their length can be adjusted during program execution after initialization.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
If you find it difficult to understand the physical structure, it is recommended that you read the next chapter, "Arrays and Linked Lists," before reviewing this section.
|
@ -0,0 +1,13 @@
|
|||||||
|
# Data Structure
|
||||||
|
|
||||||
|
<div class="center-table" markdown>
|
||||||
|
|
||||||
|
![data structure](../assets/covers/chapter_data_structure.jpg){ width="600" }
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
!!! abstract
|
||||||
|
|
||||||
|
Data structures are like a solid and varied framework.
|
||||||
|
|
||||||
|
It provides a blueprint for the orderly organization of data upon which algorithms can come alive.
|
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 1.1 Algorithms Are Everywhere
|
||||||
|
|
||||||
|
When we hear the word "algorithm", we naturally think of mathematics. However, many algorithms do not involve complex mathematics but rely more on basic logic, which is ubiquitous in our daily lives.
|
||||||
|
|
||||||
|
Before we formally discuss algorithms, an interesting fact is worth sharing: **you have already learned many algorithms unconsciously and have become accustomed to applying them in your daily life**. Below, I will give a few specific examples to prove this point.
|
||||||
|
|
||||||
|
**Example 1: Looking Up a Dictionary**. In a standard dictionary, each word corresponds to a phonetic transcription and the dictionary is organized alphabetically based on these transcriptions. Let's say we're looking for a word that begins with the letter $r$. This is typically done in the following way:
|
||||||
|
|
||||||
|
1. Open the dictionary around its midpoint and note the first letter on that page, assuming it to be $m$.
|
||||||
|
2. Given the sequence of words following the initial letter $m$, estimate where words starting with the letter $r$ might be located within the alphabetical order.
|
||||||
|
3. Iterate steps `1.` and `2.` until you find the page where the word begins with the letter $r$.
|
||||||
|
|
||||||
|
=== "<1>"
|
||||||
|
![Dictionary search step](algorithms_are_everywhere.assets/binary_search_dictionary_step1.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
=== "<2>"
|
||||||
|
![binary_search_dictionary_step2](algorithms_are_everywhere.assets/binary_search_dictionary_step2.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
=== "<3>"
|
||||||
|
![binary_search_dictionary_step3](algorithms_are_everywhere.assets/binary_search_dictionary_step3.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
=== "<4>"
|
||||||
|
![binary_search_dictionary_step4](algorithms_are_everywhere.assets/binary_search_dictionary_step4.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
=== "<5>"
|
||||||
|
![binary_search_dictionary_step5](algorithms_are_everywhere.assets/binary_search_dictionary_step5.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 1-1 Dictionary search step </p>
|
||||||
|
|
||||||
|
The skill of looking up a dictionary, essential for elementary school students, is actually the renowned binary search algorithm. Through the lens of data structures, we can view the dictionary as a sorted "array"; while from an algorithmic perspective, the series of operations in looking up a dictionary can be seen as "binary search".
|
||||||
|
|
||||||
|
**Example 2: Organizing Playing Cards**. When playing cards, we need to arrange the cards in ascending order each game, as shown in the following process.
|
||||||
|
|
||||||
|
1. Divide the playing cards into "ordered" and "unordered" parts, assuming initially that the leftmost card is already ordered.
|
||||||
|
2. Take out a card from the unordered part and insert it into the correct position in the ordered part; once completed, the leftmost two cards will be in an ordered sequence.
|
||||||
|
3. Continue the loop described in step `2.`, each iteration involving insertion of one card from the unordered segment into the ordered portion, until all cards are appropriately ordered.
|
||||||
|
|
||||||
|
![Playing cards sorting process](algorithms_are_everywhere.assets/playing_cards_sorting.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 1-2 Playing cards sorting process </p>
|
||||||
|
|
||||||
|
The above method of organizing playing cards is essentially the "insertion sort" algorithm, which is very efficient for small datasets. Many programming languages' sorting library functions include insertion sort.
|
||||||
|
|
||||||
|
**Example 3: Making Change**. Suppose we buy goods worth $69$ yuan at a supermarket and give the cashier $100$ yuan, then the cashier needs to give us $31$ yuan in change. They would naturally complete the thought process as shown below.
|
||||||
|
|
||||||
|
1. The options are currencies smaller than $31$, including $1$, $5$, $10$, and $20$.
|
||||||
|
2. Take out the largest $20$ from the options, leaving $31 - 20 = 11$.
|
||||||
|
3. Take out the largest $10$ from the remaining options, leaving $11 - 10 = 1$.
|
||||||
|
4. Take out the largest $1$ from the remaining options, leaving $1 - 1 = 0$.
|
||||||
|
5. Complete the change-making, with the solution being $20 + 10 + 1 = 31$.
|
||||||
|
|
||||||
|
![Change making process](algorithms_are_everywhere.assets/greedy_change.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 1-3 Change making process </p>
|
||||||
|
|
||||||
|
In the aforementioned steps, at each stage, we make the optimal choice (utilizing the highest denomination possible), ultimately deriving at a feasible change-making approach. From the perspective of data structures and algorithms, this approach is essentially a "greedy" algorithm.
|
||||||
|
|
||||||
|
From preparing a dish to traversing interstellar realms, virtually every problem-solving endeavor relies on algorithms. The emergence of computers enables us to store data structures in memory and write code to call CPUs and GPUs to execute algorithms. Consequently, we can transfer real-life predicaments to computers, efficiently addressing a myriad of complex issues.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
If concepts such as data structures, algorithms, arrays, and binary search still seem somewhat obsecure, I encourage you to continue reading. This book will gently guide you into the realm of understanding data structures and algorithms.
|
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
icon: material/calculator-variant-outline
|
||||||
|
---
|
||||||
|
|
||||||
|
# 第 1 章 Introduction to Algorithms
|
||||||
|
|
||||||
|
<div class="center-table" markdown>
|
||||||
|
|
||||||
|
![A first look at the algorithm](../assets/covers/chapter_introduction.jpg){ width="600" }{ class="cover-image" }
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
!!! abstract
|
||||||
|
|
||||||
|
A graceful maiden dances, intertwined with the data, her skirt swaying to the melody of algorithms.
|
||||||
|
|
||||||
|
She invites you to a dance, follow her steps, and enter the world of algorithms full of logic and beauty.
|
||||||
|
|
||||||
|
## 本章内容
|
||||||
|
|
||||||
|
- [1.1 Algorithms Are Everywhere](https://www.hello-algo.com/chapter_introduction/algorithms_are_everywhere/)
|
||||||
|
- [1.2 What is Algorithms](https://www.hello-algo.com/chapter_introduction/what_is_dsa/)
|
||||||
|
- [1.3 Summary](https://www.hello-algo.com/chapter_introduction/summary/)
|
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 1.3 Summary
|
||||||
|
|
||||||
|
- Algorithms are ubiquitous in daily life and are not as inaccessible and complex as they might seem. In fact, we have already unconsciously learned many algorithms to solve various problems in life.
|
||||||
|
- The principle of looking up a word in a dictionary is consistent with the binary search algorithm. The binary search algorithm embodies the important algorithmic concept of divide and conquer.
|
||||||
|
- The process of organizing playing cards is very similar to the insertion sort algorithm. The insertion sort algorithm is suitable for sorting small datasets.
|
||||||
|
- The steps of making change in currency essentially follow the greedy algorithm, where each step involves making the best possible choice at the moment.
|
||||||
|
- An algorithm is a set of instructions or steps used to solve a specific problem within a finite amount of time, while a data structure is the way data is organized and stored in a computer.
|
||||||
|
- Data structures and algorithms are closely linked. Data structures are the foundation of algorithms, and algorithms are the stage to utilize the functions of data structures.
|
||||||
|
- We can liken data structures and algorithms to building blocks. The blocks represent data, the shape and connection method of the blocks represent data structures, and the steps of assembling the blocks correspond to algorithms.
|
@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 1.2 What is an Algorithm
|
||||||
|
|
||||||
|
## 1.2.1 Definition of an Algorithm
|
||||||
|
|
||||||
|
An "algorithm" is a set of instructions or steps to solve a specific problem within a finite amount of time. It has the following characteristics:
|
||||||
|
|
||||||
|
- The problem is clearly defined, including unambiguous definitions of input and output.
|
||||||
|
- The algorithm is feasible, meaning it can be completed within a finite number of steps, time, and memory space.
|
||||||
|
- Each step has a definitive meaning. The output is consistently the same under the same inputs and conditions.
|
||||||
|
|
||||||
|
## 1.2.2 Definition of a Data Structure
|
||||||
|
|
||||||
|
A "data structure" is a way of organizing and storing data in a computer, with the following design goals:
|
||||||
|
|
||||||
|
- Minimize space occupancy to save computer memory.
|
||||||
|
- Make data operations as fast as possible, covering data access, addition, deletion, updating, etc.
|
||||||
|
- Provide concise data representation and logical information to enable efficient algorithm execution.
|
||||||
|
|
||||||
|
**Designing data structures is a balancing act, often requiring trade-offs**. If you want to improve in one aspect, you often need to compromise in another. Here are two examples:
|
||||||
|
|
||||||
|
- Compared to arrays, linked lists offer more convenience in data addition and deletion but sacrifice data access speed.
|
||||||
|
- Graphs, compared to linked lists, provide richer logical information but require more memory space.
|
||||||
|
|
||||||
|
## 1.2.3 Relationship Between Data Structures and Algorithms
|
||||||
|
|
||||||
|
As shown in the diagram below, data structures and algorithms are highly related and closely integrated, specifically in the following three aspects:
|
||||||
|
|
||||||
|
- Data structures are the foundation of algorithms. They provide structured data storage and methods for manipulating data for algorithms.
|
||||||
|
- Algorithms are the stage where data structures come into play. The data structure alone only stores data information; it is through the application of algorithms that specific problems can be solved.
|
||||||
|
- Algorithms can often be implemented based on different data structures, but their execution efficiency can vary greatly. Choosing the right data structure is key.
|
||||||
|
|
||||||
|
![Relationship between data structures and algorithms](what_is_dsa.assets/relationship_between_data_structure_and_algorithm.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 1-4 Relationship between data structures and algorithms </p>
|
||||||
|
|
||||||
|
Data structures and algorithms can be likened to a set of building blocks, as illustrated in the Figure 1-5 . A building block set includes numerous pieces, accompanied by detailed assembly instructions. Following these instructions step by step allows us to construct an intricate block model.
|
||||||
|
|
||||||
|
![Assembling blocks](what_is_dsa.assets/assembling_blocks.jpg){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 1-5 Assembling blocks </p>
|
||||||
|
|
||||||
|
The detailed correspondence between the two is shown in the Table 1-1 .
|
||||||
|
|
||||||
|
<p align="center"> Table 1-1 Comparing Data Structures and Algorithms to Building Blocks </p>
|
||||||
|
|
||||||
|
<div class="center-table" markdown>
|
||||||
|
|
||||||
|
| Data Structures and Algorithms | Building Blocks |
|
||||||
|
| ------------------------------ | --------------------------------------------------------------- |
|
||||||
|
| Input data | Unassembled blocks |
|
||||||
|
| Data structure | Organization of blocks, including shape, size, connections, etc |
|
||||||
|
| Algorithm | A series of steps to assemble the blocks into the desired shape |
|
||||||
|
| Output data | Completed Block model |
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
It's worth noting that data structures and algorithms are independent of programming languages. For this reason, this book is able to provide implementations in multiple programming languages.
|
||||||
|
|
||||||
|
!!! tip "Conventional Abbreviation"
|
||||||
|
|
||||||
|
In real-life discussions, we often refer to "Data Structures and Algorithms" simply as "Algorithms". For example, the well-known LeetCode algorithm problems actually test both data structure and algorithm knowledge.
|
@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 0.1 The Book
|
||||||
|
|
||||||
|
The aim of this project is to create an open source, free, novice-friendly introductory tutorial on data structures and algorithms.
|
||||||
|
|
||||||
|
- Animated graphs are used throughout the book to structure the knowledge of data structures and algorithms in a way that is clear and easy to understand with a smooth learning curve.
|
||||||
|
- The source code of the algorithms can be run with a single click, supporting Java, C++, Python, Go, JS, TS, C#, Swift, Rust, Dart, Zig and other languages.
|
||||||
|
- Readers are encouraged to help each other and make progress in the chapter discussion forums, and questions and comments can usually be answered within two days.
|
||||||
|
|
||||||
|
## 0.1.1 Target Readers
|
||||||
|
|
||||||
|
If you are a beginner to algorithms, have never touched an algorithm before, or already have some experience brushing up on data structures and algorithms, and have a vague understanding of data structures and algorithms, repeatedly jumping sideways between what you can and can't do, then this book is just for you!
|
||||||
|
|
||||||
|
If you have already accumulated a certain amount of questions and are familiar with most of the question types, then this book can help you review and organize the algorithm knowledge system, and the repository source code can be used as a "brushing tool library" or "algorithm dictionary".
|
||||||
|
|
||||||
|
If you are an algorithm expert, we look forward to receiving your valuable suggestions or [participate in the creation together](https://www.hello-algo.com/chapter_appendix/contribution/).
|
||||||
|
|
||||||
|
!!! success "precondition"
|
||||||
|
|
||||||
|
You will need to have at least a basic knowledge of programming in any language and be able to read and write simple code.
|
||||||
|
|
||||||
|
## 0.1.2 Content Structure
|
||||||
|
|
||||||
|
The main contents of the book are shown in the Figure 0-1 .
|
||||||
|
|
||||||
|
- **Complexity Analysis**: dimensions and methods of evaluation of data structures and algorithms. Methods of deriving time complexity, space complexity, common types, examples, etc.
|
||||||
|
- **Data Structures**: basic data types, classification methods of data structures. Definition, advantages and disadvantages, common operations, common types, typical applications, implementation methods of data structures such as arrays, linked lists, stacks, queues, hash tables, trees, heaps, graphs, etc.
|
||||||
|
- **Algorithms**: definitions, advantages and disadvantages, efficiency, application scenarios, solution steps, sample topics of search, sorting algorithms, divide and conquer, backtracking algorithms, dynamic programming, greedy algorithms, and more.
|
||||||
|
|
||||||
|
![Hello Algo content structure](about_the_book.assets/hello_algo_mindmap.jpg){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-1 Hello Algo content structure </p>
|
||||||
|
|
||||||
|
## 0.1.3 Acknowledgements
|
||||||
|
|
||||||
|
During the creation of this book, I received help from many people, including but not limited to:
|
||||||
|
|
||||||
|
- Thank you to my mentor at the company, Dr. Shih Lee, for encouraging me to "get moving" during one of our conversations, which strengthened my resolve to write this book.
|
||||||
|
- I would like to thank my girlfriend Bubbles for being the first reader of this book, and for making many valuable suggestions from the perspective of an algorithm whiz, making this book more suitable for newbies.
|
||||||
|
- Thanks to Tengbao, Qibao, and Feibao for coming up with a creative name for this book that evokes fond memories of writing the first line of code "Hello World!".
|
||||||
|
- Thanks to Sutong for designing the beautiful cover and logo for this book and patiently revising it many times under my OCD.
|
||||||
|
- Thanks to @squidfunk for writing layout suggestions and for developing the open source documentation theme [Material-for-MkDocs](https://github.com/squidfunk/mkdocs-material/tree/master).
|
||||||
|
|
||||||
|
During the writing process, I read many textbooks and articles on data structures and algorithms. These works provide excellent models for this book and ensure the accuracy and quality of its contents. I would like to thank all my teachers and predecessors for their outstanding contributions!
|
||||||
|
|
||||||
|
This book promotes a hands-on approach to learning, and in this respect is heavily inspired by ["Hands-On Learning for Depth"](https://github.com/d2l-ai/d2l-zh). I highly recommend this excellent book to all readers.
|
||||||
|
|
||||||
|
A heartfelt thank you to my parents, it is your constant support and encouragement that gives me the opportunity to do this fun-filled thing.
|
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
icon: material/book-open-outline
|
||||||
|
---
|
||||||
|
|
||||||
|
# 第 0 章 Preface
|
||||||
|
|
||||||
|
<div class="center-table" markdown>
|
||||||
|
|
||||||
|
![Preface](../assets/covers/chapter_preface.jpg){ width="600" }{ class="cover-image" }
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
!!! abstract
|
||||||
|
|
||||||
|
Algorithms are like a beautiful symphony, with each line of code flowing like a rhythm.
|
||||||
|
|
||||||
|
May this book ring softly in your head, leaving a unique and profound melody.
|
||||||
|
|
||||||
|
## 本章内容
|
||||||
|
|
||||||
|
- [0.1 The Book](https://www.hello-algo.com/chapter_preface/about_the_book/)
|
||||||
|
- [0.2 How to Read](https://www.hello-algo.com/chapter_preface/suggestions/)
|
||||||
|
- [0.3 Summary](https://www.hello-algo.com/chapter_preface/summary/)
|
@ -0,0 +1,240 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 0.2 How To Read
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
|
||||||
|
For the best reading experience, it is recommended that you read through this section.
|
||||||
|
|
||||||
|
## 0.2.1 Conventions Of Style
|
||||||
|
|
||||||
|
- Those labeled `*` after the title are optional chapters with relatively difficult content. If you have limited time, it is advisable to skip them.
|
||||||
|
- Proper nouns and words and phrases with specific meanings are marked with `"double quotes"` to avoid ambiguity.
|
||||||
|
- Important proper nouns and their English translations are marked with `" "` in parentheses, e.g. `"array array"` . It is recommended to memorize them for reading the literature.
|
||||||
|
- **Bolded text** Indicates key content or summary statements, which deserve special attention.
|
||||||
|
- When it comes to terms that are inconsistent between programming languages, this book follows Python, for example using $\text{None}$ to mean "empty".
|
||||||
|
- This book partially abandons the specification of annotations in programming languages in exchange for a more compact layout of the content. There are three main types of annotations: title annotations, content annotations, and multi-line annotations.
|
||||||
|
|
||||||
|
=== "Python"
|
||||||
|
|
||||||
|
```python title=""
|
||||||
|
"""Header comments for labeling functions, classes, test samples, etc.""""
|
||||||
|
|
||||||
|
# Content comments for detailed code solutions
|
||||||
|
|
||||||
|
"""
|
||||||
|
multi-line
|
||||||
|
marginal notes
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "C++"
|
||||||
|
|
||||||
|
```cpp title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Java"
|
||||||
|
|
||||||
|
```java title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "C#"
|
||||||
|
|
||||||
|
```csharp title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Go"
|
||||||
|
|
||||||
|
```go title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Swift"
|
||||||
|
|
||||||
|
```swift title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "JS"
|
||||||
|
|
||||||
|
```javascript title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "TS"
|
||||||
|
|
||||||
|
```typescript title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Dart"
|
||||||
|
|
||||||
|
```dart title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Rust"
|
||||||
|
|
||||||
|
```rust title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "C"
|
||||||
|
|
||||||
|
```c title=""
|
||||||
|
/* Header comments for labeling functions, classes, test samples, etc. */
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multi-line
|
||||||
|
* marginal notes
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Zig"
|
||||||
|
|
||||||
|
```zig title=""
|
||||||
|
// Header comments for labeling functions, classes, test samples, etc.
|
||||||
|
|
||||||
|
// Content comments for detailed code solutions.
|
||||||
|
|
||||||
|
// Multi-line
|
||||||
|
// Annotation
|
||||||
|
```
|
||||||
|
|
||||||
|
## 0.2.2 Learn Efficiently In Animated Graphic Solutions
|
||||||
|
|
||||||
|
Compared with text, videos and pictures have a higher degree of information density and structure and are easier to understand. In this book, **key and difficult knowledge will be presented mainly in the form of animations and graphs**, while the text serves as an explanation and supplement to the animations and graphs.
|
||||||
|
|
||||||
|
If, while reading the book, you find that a particular paragraph provides an animation or a graphic solution as shown below, **please use the figure as the primary source and the text as a supplement and synthesize the two to understand the content**.
|
||||||
|
|
||||||
|
![Example animation](../index.assets/animation.gif){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-2 Example animation </p>
|
||||||
|
|
||||||
|
## 0.2.3 Deeper Understanding In Code Practice
|
||||||
|
|
||||||
|
The companion code for this book is hosted in the [GitHub repository](https://github.com/krahets/hello-algo). As shown in the Figure 0-3 , **the source code is accompanied by test samples that can be run with a single click**.
|
||||||
|
|
||||||
|
If time permits, **it is recommended that you refer to the code and knock it through on your own**. If you have limited time to study, please read through and run all the code at least once.
|
||||||
|
|
||||||
|
The process of writing code is often more rewarding than reading it. **Learning by doing is really learning**.
|
||||||
|
|
||||||
|
![Running code example](../index.assets/running_code.gif){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-3 Running code example </p>
|
||||||
|
|
||||||
|
The preliminaries for running the code are divided into three main steps.
|
||||||
|
|
||||||
|
**Step 1: Install the local programming environment**. Please refer to [Appendix Tutorial](https://www.hello-algo.com/chapter_appendix/installation/) for installation, or skip this step if already installed.
|
||||||
|
|
||||||
|
**Step 2: Clone or download the code repository**. If [Git](https://git-scm.com/downloads) is already installed, you can clone this repository with the following command.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://github.com/krahets/hello-algo.git
|
||||||
|
```
|
||||||
|
|
||||||
|
Of course, you can also in the location shown in the Figure 0-4 , click "Download ZIP" directly download the code zip, and then in the local solution.
|
||||||
|
|
||||||
|
![Clone repository with download code](suggestions.assets/download_code.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-4 Clone repository with download code </p>
|
||||||
|
|
||||||
|
**Step 3: Run the source code**. As shown in the Figure 0-5 , for the code block labeled with the file name at the top, we can find the corresponding source code file in the `codes` folder of the repository. The source code files can be run with a single click, which will help you save unnecessary debugging time and allow you to focus on what you are learning.
|
||||||
|
|
||||||
|
![Code block with corresponding source file](suggestions.assets/code_md_to_repo.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-5 Code block with corresponding source file </p>
|
||||||
|
|
||||||
|
## 0.2.4 Growing Together In Questioning And Discussion
|
||||||
|
|
||||||
|
While reading this book, please don't skip over the points that you didn't learn. **Feel free to ask your questions in the comment section**. We will be happy to answer them and can usually respond within two days.
|
||||||
|
|
||||||
|
As you can see in the Figure 0-6 , each post comes with a comment section at the bottom. I hope you'll pay more attention to the comments section. On the one hand, you can learn about the problems that people encounter, so as to check the gaps and stimulate deeper thinking. On the other hand, we expect you to generously answer other partners' questions, share your insights, and help others improve.
|
||||||
|
|
||||||
|
![Example of comment section](../index.assets/comment.gif){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-6 Example of comment section </p>
|
||||||
|
|
||||||
|
## 0.2.5 Algorithm Learning Route
|
||||||
|
|
||||||
|
From a general point of view, we can divide the process of learning data structures and algorithms into three stages.
|
||||||
|
|
||||||
|
1. **Introduction to Algorithms**. We need to familiarize ourselves with the characteristics and usage of various data structures and learn about the principles, processes, uses and efficiency of different algorithms.
|
||||||
|
2. **Brush up on algorithm questions**. It is recommended to start brushing from popular topics, such as [Sword to Offer](https://leetcode.cn/studyplan/coding-interviews/) and [LeetCode Hot 100](https://leetcode.cn/studyplan/top-100- liked/), first accumulate at least 100 questions to familiarize yourself with mainstream algorithmic problems. Forgetfulness can be a challenge when first brushing up, but rest assured that this is normal. We can follow the "Ebbinghaus Forgetting Curve" to review the questions, and usually after 3-5 rounds of repetitions, we will be able to memorize them.
|
||||||
|
3. **Build the knowledge system**. In terms of learning, we can read algorithm column articles, solution frameworks and algorithm textbooks to continuously enrich the knowledge system. In terms of brushing, we can try to adopt advanced brushing strategies, such as categorizing by topic, multiple solutions, multiple solutions, etc. Related brushing tips can be found in various communities.
|
||||||
|
|
||||||
|
As shown in the Figure 0-7 , this book mainly covers "Phase 1" and is designed to help you start Phase 2 and 3 more efficiently.
|
||||||
|
|
||||||
|
![algorithm learning route](suggestions.assets/learning_route.png){ class="animation-figure" }
|
||||||
|
|
||||||
|
<p align="center"> Figure 0-7 algorithm learning route </p>
|
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
comments: true
|
||||||
|
---
|
||||||
|
|
||||||
|
# 0.3 Summary
|
||||||
|
|
||||||
|
- The main audience of this book is beginners in algorithm. If you already have some basic knowledge, this book can help you systematically review your algorithm knowledge, and the source code in this book can also be used as a "Coding Toolkit".
|
||||||
|
- The book consists of three main sections, Complexity Analysis, Data Structures, and Algorithms, covering most of the topics in the field.
|
||||||
|
- For newcomers to algorithms, it is crucial to read an introductory book in the beginning stages to avoid many detours or common pitfalls.
|
||||||
|
- Animations and graphs within the book are usually used to introduce key points and difficult knowledge. These should be given more attention when reading the book.
|
||||||
|
- Practice is the best way to learn programming. It is highly recommended that you run the source code and type in the code yourself.
|
||||||
|
- Each chapter in the web version of this book features a discussion forum, and you are welcome to share your questions and insights at any time.
|
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |