1. 二分查找 (Binary Search)
原理:在已排序数组中,通过每次折半缩小范围查找目标值。
实现:
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
案例:
// 案例:查找学生成绩表中某个分数的位置
const scores = [60, 72, 85, 90, 95, 98, 100];
const targetScore = 90;
const position = binarySearch(scores, targetScore);
console.log(`分数 ${targetScore} 在第 ${position} 个位置`); // 输出: 分数 90 在第 3 个位置
const notFound = binarySearch(scores, 88);
console.log(`查找 88: ${notFound}`); // 输出: 查找 88: -1
复杂度:时间 O(log n),空间 O(1)。
应用:快速定位有序数据,如查找书籍编号。
2. 洗牌 (Shuffle Array, Fisher-Yates Algorithm)
原理:从数组末尾向前,每次随机交换元素,保证均匀分布。
实现:
function shuffleArray(arr) {
const result = [...arr];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
案例:
// 案例:随机排列一副扑克牌(简化版)
const cards = ['A♠', 'K♠', 'Q♠', 'J♠', '10♠'];
const shuffled = shuffleArray(cards);
console.log('洗牌结果:', shuffled);
// 输出示例: 洗牌结果: ['Q♠', '10♠', 'A♠', 'J♠', 'K♠']
复杂度:时间 O(n),空间 O(1)(复制版本 O(n))。
应用:游戏中随机发牌、随机推荐内容。
3. 去重与交集 (Array Deduplication & Intersection)
原理:利用 Set 的高效去重和查找特性。
实现:
function uniqueArray(arr) {
return [...new Set(arr)];
}
function arrayIntersection(arr1, arr2) {
const set2 = new Set(arr2);
return arr1.filter(item => set2.has(item));
}
案例:
// 案例1:清理重复的用户ID
const userIds = [101, 102, 103, 102, 104, 101];
const uniqueIds = uniqueArray(userIds);
console.log('去重后的ID:', uniqueIds); // 输出: 去重后的ID: [101, 102, 103, 104]
// 案例2:找出两个团队的共同成员
const teamA = ['Alice', 'Bob', 'Charlie'];
const teamB = ['Bob', 'David', 'Charlie'];
const commonMembers = arrayIntersection(teamA, teamB);
console.log('共同成员:', commonMembers); // 输出: 共同成员: ['Bob', 'Charlie']
复杂度:
- 去重:时间 O(n),空间 O(n)。
- 交集:时间 O(n + m),空间 O(m)。
应用:数据清洗、查找共同兴趣用户。
4. 最长公共子序列 (Longest Common Subsequence, LCS)
原理:通过动态规划比较两个字符串,计算最长公共子序列长度。
实现:
function longestCommonSubsequence(str1, str2) {
const m = str1.length;
const n = str2.length;
const dp = Array(m + 1).fill().map(() => Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) {
for (let j = 1; j <= n; j++) {
if (str1[i - 1] === str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[m][n];
}
案例:
// 案例:比较两个单词的相似度
const word1 = "HELLO";
const word2 = "HALO";
const lcsLength = longestCommonSubsequence(word1, word2);
console.log(`"${word1}" 和 "${word2}" 的LCS长度: ${lcsLength}`);
// 输出: "HELLO" 和 "HALO" 的LCS长度: 4
// 案例:DNA序列匹配
const dna1 = "AGGTAB";
const dna2 = "GXTXAYB";
const dnaLcs = longestCommonSubsequence(dna1, dna2);
console.log(`DNA序列的LCS长度: ${dnaLcs}`); // 输出: DNA序列的LCS长度: 4
复杂度:时间 O(mn),空间 O(mn)。
应用:文本对比、生物信息学。
5. 快速幂 (Fast Exponentiation)
原理:通过二分法将幂运算分解为平方和乘法,优化计算。
实现:
function fastPower(base, exponent) {
if (exponent === 0) return 1;
if (exponent < 0) return 1 / fastPower(base, -exponent);
const half = fastPower(base, Math.floor(exponent / 2));
return exponent % 2 === 0 ? half * half : half * half * base;
}
案例:
// 案例1:计算大数的幂
const result1 = fastPower(2, 10);
console.log(`2^10 = ${result1}`); // 输出: 2^10 = 1024
// 案例2:计算负指数
const result2 = fastPower(2, -3);
console.log(`2^-3 = ${result2}`); // 输出: 2^-3 = 0.125
复杂度:时间 O(log n),空间 O(log n)。
应用:密码学(如RSA)、高效数学计算。
6. 前缀和 (Prefix Sum)
原理:预计算累积和,快速查询区间和。
实现:
function createPrefixSum(arr) {
const prefixSum = [0];
for (let i = 0; i < arr.length; i++) {
prefixSum[i + 1] = prefixSum[i] + arr[i];
}
return (start, end) => prefixSum[end + 1] - prefixSum[start];
}
案例:
// 案例:统计一周每天的销售额区间总和
const sales = [100, 150, 200, 120, 180, 90, 110]; // 7天销售额
const getRangeSum = createPrefixSum(sales);
// 周一到周三的总销售额
const weekStart = getRangeSum(0, 2);
console.log(`周一到周三总销售额: ${weekStart}`); // 输出: 周一到周三总销售额: 450
// 周四到周日总销售额
const weekEnd = getRangeSum(3, 6);
console.log(`周四到周日总销售额: ${weekEnd}`); // 输出: 周四到周日总销售额: 500
复杂度:
- 预处理:时间 O(n),空间 O(n)。
- 查询:时间 O(1)。
应用:区间统计、实时数据分析。
综合对比与案例总结
算法 | 时间复杂度 | 空间复杂度 | 案例输出示例 |
---|---|---|---|
二分查找 | O(log n) | O(1) | 查找 90: 位置 3 |
洗牌 | O(n) | O(1) | 洗牌: ['Q♠', '10♠', ...] |
去重 | O(n) | O(n) | 去重ID: [101, 102, 103, 104] |
交集 | O(n + m) | O(m) | 共同成员: ['Bob', 'Charlie'] |
LCS | O(m*n) | O(m*n) | LCS长度: 4 (HELLO, HALO) |
快速幂 | O(log n) | O(log n) | 2^10 = 1024 |
前缀和 | O(n) / O(1) | O(n) | 周一到周三: 450 |
前端工程师、程序员
标签:
JavaScript
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)