数组搜索是数据结构和算法(DSA)中的基本概念。这篇博文将介绍使用 JavaScript 的各种数组搜索技术,从基础到高级。我们将探索 20 个示例,讨论时间复杂度,并提供 LeetCode 练习问题。
目录
- 线性搜索
- 二分查找
- 跳转搜索
- 插值搜索
- 指数搜索
- 子数组搜索
- 双指针技术
- 滑动窗口技术
- 高级搜索技术
- LeetCode 练习题
1. 线性搜索
线性搜索是最简单的搜索算法,适用于排序和未排序的数组。
时间复杂度: O(n),其中 n 是数组中的元素数量。
示例 1:基本线性搜索
function linearSearch(arr, target) { for (let i = 0; i <h3> 示例 2:查找所有出现的情况 </h3> <pre class="brush:php;toolbar:false">function findAllOccurrences(arr, target) { const result = []; for (let i = 0; i <h2> 2.二分查找 </h2> <p>二分搜索是一种在排序数组中搜索的有效算法。</p> <p><strong>时间复杂度:</strong> O(log n)</p> <h3> 示例 3:迭代二分搜索 </h3> <pre class="brush:php;toolbar:false">function binarySearch(arr, target) { let left = 0; let right = arr.length - 1; while (left <h3> 示例 4:递归二分查找 </h3> <pre class="brush:php;toolbar:false">function recursiveBinarySearch(arr, target, left = 0, right = arr.length - 1) { if (left > right) { return -1; } const mid = Math.floor((left + right) / 2); if (arr[mid] === target) { return mid; } else if (arr[mid] <h2> 3. 跳转搜索 </h2> <p>跳跃搜索是一种排序数组算法,它通过跳过一些元素来减少比较次数。</p> <p><strong>时间复杂度:</strong> O(√n)</p> <h3> 示例 5:跳转搜索实现 </h3> <pre class="brush:php;toolbar:false">function jumpSearch(arr, target) { const n = arr.length; const step = Math.floor(Math.sqrt(n)); let prev = 0; while (arr[Math.min(step, n) - 1] = n) { return -1; } } while (arr[prev] <h2> 4. 插值搜索 </h2> <p>插值搜索是针对均匀分布排序数组的二分搜索的改进变体。</p> <p><strong>时间复杂度:</strong> 对于均匀分布的数据,O(log log n),最坏情况下为 O(n)。</p> <h3> 示例 6:插值搜索实现 </h3> <pre class="brush:php;toolbar:false">function interpolationSearch(arr, target) { let low = 0; let high = arr.length - 1; while (low = arr[low] && target <h2> 5. 指数搜索 </h2> <p>指数搜索对于无界搜索很有用,也适用于有界数组。</p> <p><strong>时间复杂度:</strong> O(log n)</p> <h3> 示例 7:指数搜索实现 </h3> <pre class="brush:php;toolbar:false">function exponentialSearch(arr, target) { if (arr[0] === target) { return 0; } let i = 1; while (i <h2> 6. 子数组搜索 </h2> <p>在较大数组中搜索子数组是 DSA 中的常见问题。</p> <h3> 示例 8:朴素子数组搜索 </h3> <p><strong>时间复杂度:</strong> O(n * m),其中 n 是主数组的长度,m 是子数组的长度。<br> </p> <pre class="brush:php;toolbar:false">function naiveSubarraySearch(arr, subArr) { for (let i = 0; i <h3> 示例 9:用于子数组搜索的 KMP 算法 </h3> <p><strong>时间复杂度:</strong> O(n + m)<br> </p> <pre class="brush:php;toolbar:false">function kmpSearch(arr, pattern) { const n = arr.length; const m = pattern.length; const lps = computeLPS(pattern); let i = 0, j = 0; while (i <h2> 7. 两指针技术 </h2> <p>两指针技术通常用于在排序数组中搜索或处理对时。</p> <h3> 示例 10:查找具有给定总和的对 </h3> <p><strong>时间复杂度:</strong> O(n)<br> </p> <pre class="brush:php;toolbar:false">function findPairWithSum(arr, target) { let left = 0; let right = arr.length - 1; while (left <h3> 例 11:三和问题 </h3> <p><strong>时间复杂度:</strong> O(n^2)<br> </p> <pre class="brush:php;toolbar:false">function threeSum(arr, target) { arr.sort((a, b) => a - b); const result = []; for (let i = 0; i 0 && arr[i] === arr[i - 1]) continue; let left = i + 1; let right = arr.length - 1; while (left <h2> 8. 滑动窗口技术 </h2> <p>滑动窗口技术对于解决具有连续元素的数组/字符串问题非常有用。</p> <h3> 示例 12:大小为 K 的最大和子数组 </h3> <p><strong>时间复杂度:</strong> O(n)<br> </p> <pre class="brush:php;toolbar:false">function maxSumSubarray(arr, k) { let maxSum = 0; let windowSum = 0; for (let i = 0; i <h3> 示例 13:具有 K 个不同字符的最长子字符串 </h3> <p><strong>时间复杂度:</strong> O(n)<br> </p> <pre class="brush:php;toolbar:false">function longestSubstringKDistinct(s, k) { const charCount = new Map(); let left = 0; let maxLength = 0; for (let right = 0; right k) { charCount.set(s[left], charCount.get(s[left]) - 1); if (charCount.get(s[left]) === 0) { charCount.delete(s[left]); } left++; } maxLength = Math.max(maxLength, right - left + 1); } return maxLength; } const s = "aabacbebebe"; console.log(longestSubstringKDistinct(s, 3)); // Output: 7
9. 高级搜索技术
示例 14:在旋转排序数组中搜索
时间复杂度: O(log n)
function searchRotatedArray(arr, target) { let left = 0; let right = arr.length - 1; while (left = arr[left] && target arr[mid] && target <h3> 示例 15:在 2D 矩阵中搜索 </h3> <p><strong>时间复杂度:</strong> O(log(m * n)),其中 m 是行数,n 是列数<br> </p> <pre class="brush:php;toolbar:false">function searchMatrix(matrix, target) { if (!matrix.length || !matrix[0].length) return false; const m = matrix.length; const n = matrix[0].length; let left = 0; let right = m * n - 1; while (left <h3> 示例 16:查找峰值元素 </h3> <p><strong>时间复杂度:</strong> O(log n)<br> </p> <pre class="brush:php;toolbar:false">function findPeakElement(arr) { let left = 0; let right = arr.length - 1; while (left arr[mid + 1]) { right = mid; } else { left = mid + 1; } } return left; } const arr = [1, 2, 1, 3, 5, 6, 4]; console.log(findPeakElement(arr)); // Output: 5
示例 17:在未知大小的排序数组中搜索
时间复杂度: O(log n)
function searchUnknownSize(arr, target) { let left = 0; let right = 1; while (arr[right] <h3> 示例 18:查找旋转排序数组中的最小值 </h3> <p><strong>时间复杂度:</strong> O(log n)<br> </p> <pre class="brush:php;toolbar:false">function findMin(arr) { let left = 0; let right = arr.length - 1; while (left arr[right]) { left = mid + 1; } else { right = mid; } } return arr[left]; } const rotatedArr = [4, 5, 6, 7, 0, 1, 2]; console.log(findMin(rotatedArr)); // Output: 0
示例 19:搜索范围
时间复杂度: O(log n)
function searchRange(arr, target) { const left = findBound(arr, target, true); if (left === -1) return [-1, -1]; const right = findBound(arr, target, false); return [left, right]; } function findBound(arr, target, isLeft) { let left = 0; let right = arr.length - 1; let result = -1; while (left <h3> 示例 20:两个排序数组的中值 </h3> <p><strong>时间复杂度:</strong> O(log(min(m, n))),其中 m 和 n 是两个数组的长度<br> </p> <pre class="brush:php;toolbar:false">function findMedianSortedArrays(nums1, nums2) { if (nums1.length > nums2.length) { return findMedianSortedArrays(nums2, nums1); } const m = nums1.length; const n = nums2.length; let left = 0; let right = m; while (left minRightY) { right = partitionX - 1; } else { left = partitionX + 1; } } throw new Error("Input arrays are not sorted."); } const nums1 = [1, 3]; const nums2 = [2]; console.log(findMedianSortedArrays(nums1, nums2)); // Output: 2
10.LeetCode练习题
为了进一步测试您对数组搜索的理解和技能,您可以练习以下 15 个 LeetCode 问题:
- 两和
- 在旋转排序数组中搜索
- 查找旋转排序数组中的最小值
- 搜索二维矩阵
- 找到峰值元素
- 搜索范围
- 两个排序数组的中值
- 数组中的第 K 个最大元素
- 查找 K 个最接近的元素
- 在未知大小的排序数组中搜索
- D 天内运送包裹的能力
- 科科吃香蕉
- 查找重复的数字
- 最多包含 K 个不同字符的最长子字符串
- 子数组和等于 K
这些问题涵盖了广泛的数组搜索技术,并将帮助您巩固对本博文中讨论的概念的理解。
总之,掌握数组搜索技术对于精通数据结构和算法至关重要。通过理解和实现这些不同的方法,您将能够更好地解决复杂的问题并优化您的代码。请记住分析每种方法的时间和空间复杂度,并根据您问题的具体要求选择最合适的一种。
祝您编码和搜索愉快!
以上是使用 JavaScript 在 DSA 中进行数组搜索:从基础到高级的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

本教程向您展示了如何将自定义的Google搜索API集成到您的博客或网站中,提供了比标准WordPress主题搜索功能更精致的搜索体验。 令人惊讶的是简单!您将能够将搜索限制为Y

本文系列在2017年中期进行了最新信息和新示例。 在此JSON示例中,我们将研究如何使用JSON格式将简单值存储在文件中。 使用键值对符号,我们可以存储任何类型的

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

利用轻松的网页布局:8个基本插件 jQuery大大简化了网页布局。 本文重点介绍了简化该过程的八个功能强大的JQuery插件,对于手动网站创建特别有用

核心要点 JavaScript 中的 this 通常指代“拥有”该方法的对象,但具体取决于函数的调用方式。 没有当前对象时,this 指代全局对象。在 Web 浏览器中,它由 window 表示。 调用函数时,this 保持全局对象;但调用对象构造函数或其任何方法时,this 指代对象的实例。 可以使用 call()、apply() 和 bind() 等方法更改 this 的上下文。这些方法使用给定的 this 值和参数调用函数。 JavaScript 是一门优秀的编程语言。几年前,这句话可

jQuery是一个很棒的JavaScript框架。但是,与任何图书馆一样,有时有必要在引擎盖下发现发生了什么。也许是因为您正在追踪一个错误,或者只是对jQuery如何实现特定UI感到好奇

该帖子编写了有用的作弊表,参考指南,快速食谱以及用于Android,BlackBerry和iPhone应用程序开发的代码片段。 没有开发人员应该没有他们! 触摸手势参考指南(PDF) Desig的宝贵资源


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)