01-React基础入门——12-组件通信大全
2026/6/9 11:36:33
对前端开发者而言,学习算法绝非为了“炫技”。它是你从“页面构建者”迈向“复杂系统设计者”的关键阶梯。它将你的编码能力从“实现功能”提升到“设计优雅、高效解决方案”的层面。从现在开始,每天投入一小段时间,结合前端场景去理解和练习,你将会感受到自身技术视野和问题解决能力的质的飞跃。------ 算法:资深前端开发者的进阶引擎
给定一个不含重复数字的整数数组nums,返回其所有可能的全排列。你可以按任意顺序返回答案。
示例:
输入:nums = [1,2,3] 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]约束条件:
1 <= nums.length <= 6-10 <= nums[i] <= 10nums中的所有整数互不相同全排列问题是计算机科学中的经典回溯问题,要求生成给定集合中所有元素的所有可能排列。对于n个不同元素,共有n!种排列。
| 方法 | 时间复杂度 | 空间复杂度 | 是否最优解 |
|---|---|---|---|
| 回溯法(路径记录) | O(n×n!) | O(n) | ✅ |
| 交换法(原地交换) | O(n×n!) | O(n) | ✅ |
最优解推荐:回溯法(路径记录)是最直观且易于理解的方法,适合面试和实际开发。
使用深度优先搜索(DFS)构建排列树,通过used数组记录已使用的元素,path数组记录当前路径。
通过在原数组上交换元素位置来生成排列,减少空间使用。
/** * 回溯法解决全排列问题 * @param {number[]} nums * @return {number[][]} */constpermute=function(nums){constresult=[];// 存储所有排列结果constused=newArray(nums.length).fill(false);// 标记元素是否使用过constpath=[];// 当前路径/** * 回溯函数 * @param {number[]} path - 当前路径 * @param {boolean[]} used - 使用标记数组 */constbacktrack=(path,used)=>{// 终止条件:路径长度等于数组长度if(path.length===nums.length){result.push([...path]);// 深拷贝当前路径return;}// 遍历所有选择for(leti=0;i<nums.length;i++){// 跳过已使用的元素if(used[i])continue;// 做选择used[i]=true;path.push(nums[i]);// 递归进入下一层backtrack(path,used);// 撤销选择(回溯)path.pop();used[i]=false;}};backtrack(path,used);returnresult;};// 测试用例console.log(permute([1,2,3]));// 输出: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]/** * 交换法解决全排列问题 * @param {number[]} nums * @return {number[][]} */constpermuteSwap=function(nums){constresult=[];/** * 交换法回溯 * @param {number} start - 当前交换起始位置 */constbacktrack=(start)=>{// 当起始位置到达数组末尾,找到一个排列if(start===nums.length){result.push([...nums]);// 深拷贝当前数组return;}// 从start位置开始,将每个元素交换到start位置for(leti=start;i<nums.length;i++){// 交换元素[nums[start],nums[i]]=[nums[i],nums[start]];// 递归处理下一个位置backtrack(start+1);// 恢复交换(回溯)[nums[start],nums[i]]=[nums[i],nums[start]];}};backtrack(0);returnresult;};// 测试用例console.log(permuteSwap([1,2,3]));| 实现方法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
|---|---|---|---|---|
| 回溯法(路径记录) | O(n×n!) | O(n) | 直观易懂,易于调试 | 需要used数组额外空间 |
| 交换法(原地交换) | O(n×n!) | O(1)额外空间 | 空间效率高 | 破坏原数组顺序,逻辑稍复杂 |
复杂度说明:
// 根据用户权限动态生成路由排列组合functiongenerateRoutePermutations(routes,userPermissions){constavailableRoutes=routes.filter(route=>userPermissions.includes(route.permission));// 生成所有可能的页面访问顺序returnpermute(availableRoutes.map(r=>r.path));}// 多个图表组件的展示顺序排列constchartComponents=['lineChart','barChart','pieChart','table'];constallLayouts=permute(chartComponents);// 用于A/B测试不同布局效果// 根据用户习惯优化表单字段顺序functionoptimizeFormOrder(fields,userBehaviorData){constpermutations=permute(fields);// 根据用户行为数据选择最优排列returnfindBestPermutation(permutations,userBehaviorData);}// 生成参数的不同排列组合进行测试functiongenerateTestCases(params){constparamValues=Object.values(params);constpermutations=permute(paramValues);returnpermutations.map(perm=>{consttestCase={};Object.keys(params).forEach((key,index)=>{testCase[key]=perm[index];});returntestCase;});}