mirror of
https://github.com/krahets/hello-algo.git
synced 2026-08-31 04:17:14 +00:00
build
This commit is contained in:
@@ -12,7 +12,7 @@ comments: true
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 二分查找示例数据 </p>
|
||||
<p align="center"> 图:二分查找示例数据 </p>
|
||||
|
||||
对于上述问题,我们先初始化指针 $i = 0$ 和 $j = n - 1$ ,分别指向数组首元素和尾元素,代表搜索区间 $[0, n - 1]$ 。请注意,中括号表示闭区间,其包含边界值本身。
|
||||
|
||||
@@ -47,6 +47,8 @@ comments: true
|
||||
=== "<7>"
|
||||

|
||||
|
||||
<p align="center"> 图:binary_search_step1 </p>
|
||||
|
||||
值得注意的是,由于 $i$ 和 $j$ 都是 `int` 类型,**因此 $i + j$ 可能会超出 `int` 类型的取值范围**。为了避免大数越界,我们通常采用公式 $m = \lfloor {i + (j - i) / 2} \rfloor$ 来计算中点。
|
||||
|
||||
=== "Java"
|
||||
@@ -627,7 +629,7 @@ comments: true
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 两种区间定义 </p>
|
||||
<p align="center"> 图:两种区间定义 </p>
|
||||
|
||||
## 10.1.2. 优点与局限性
|
||||
|
||||
|
||||
@@ -164,7 +164,7 @@ status: new
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 将查找右边界转化为查找左边界 </p>
|
||||
<p align="center"> 图:将查找右边界转化为查找左边界 </p>
|
||||
|
||||
请注意,返回的插入点是 $i$ ,因此需要将其减 $1$ ,从而获得 $j$ 。
|
||||
|
||||
@@ -321,7 +321,7 @@ status: new
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 将查找边界转化为查找元素 </p>
|
||||
<p align="center"> 图:将查找边界转化为查找元素 </p>
|
||||
|
||||
代码在此省略,值得注意的有:
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ status: new
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 二分查找插入点示例数据 </p>
|
||||
<p align="center"> 图:二分查找插入点示例数据 </p>
|
||||
|
||||
如果想要复用上节的二分查找代码,则需要回答以下两个问题。
|
||||
|
||||
@@ -203,7 +203,7 @@ status: new
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 线性查找重复元素的插入点 </p>
|
||||
<p align="center"> 图:线性查找重复元素的插入点 </p>
|
||||
|
||||
此方法虽然可用,但其包含线性查找,因此时间复杂度为 $O(n)$ 。当数组中存在很多重复的 `target` 时,该方法效率很低。
|
||||
|
||||
@@ -238,6 +238,8 @@ status: new
|
||||
=== "<8>"
|
||||

|
||||
|
||||
<p align="center"> 图:二分查找重复元素的插入点的步骤 </p>
|
||||
|
||||
观察以下代码,判断分支 `nums[m] > target` 和 `nums[m] == target` 的操作相同,因此两者可以合并。
|
||||
|
||||
即便如此,我们仍然可以将判断条件保持展开,因为其逻辑更加清晰、可读性更好。
|
||||
|
||||
@@ -16,7 +16,7 @@ comments: true
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 线性查找求解两数之和 </p>
|
||||
<p align="center"> 图:线性查找求解两数之和 </p>
|
||||
|
||||
=== "Java"
|
||||
|
||||
@@ -199,6 +199,7 @@ comments: true
|
||||
/* 方法一: 暴力枚举 */
|
||||
List<int> twoSumBruteForce(List<int> nums, int target) {
|
||||
int size = nums.length;
|
||||
// 两层循环,时间复杂度 O(n^2)
|
||||
for (var i = 0; i < size - 1; i++) {
|
||||
for (var j = i + 1; j < size; j++) {
|
||||
if (nums[i] + nums[j] == target) return [i, j];
|
||||
@@ -244,6 +245,8 @@ comments: true
|
||||
=== "<3>"
|
||||

|
||||
|
||||
<p align="center"> 图:辅助哈希表求解两数之和 </p>
|
||||
|
||||
实现代码如下所示,仅需单层循环即可。
|
||||
|
||||
=== "Java"
|
||||
@@ -469,7 +472,9 @@ comments: true
|
||||
/* 方法二: 辅助哈希表 */
|
||||
List<int> twoSumHashTable(List<int> nums, int target) {
|
||||
int size = nums.length;
|
||||
// 辅助哈希表,空间复杂度 O(n)
|
||||
Map<int, int> dic = HashMap();
|
||||
// 单层循环,时间复杂度 O(n)
|
||||
for (var i = 0; i < size; i++) {
|
||||
if (dic.containsKey(target - nums[i])) {
|
||||
return [dic[target - nums[i]]!, i];
|
||||
|
||||
@@ -46,7 +46,7 @@ comments: true
|
||||
|
||||

|
||||
|
||||
<p align="center"> Fig. 多种搜索策略 </p>
|
||||
<p align="center"> 图:多种搜索策略 </p>
|
||||
|
||||
上述几种方法的操作效率与特性如下表所示。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user