wordpress站内计费搜索wamp和wordpress
文章链接
491.递增子序列
哈希去重:用 HashSet 保证:每一层只尝试一个值。
剪枝逻辑:
-  如果当前 nums[i]比 path 中最后一个元素小,说明不是递增序列,跳过;
-  如果 nums[i]已经在当前 for 循环层尝试过了,也跳过(避免重复分支)。
回溯核心思想是:从左到右选择一个数,然后递归往后选更多数,形成子序列。
-  对于每一个位置 i,有两种选择:
-  选:将 nums[i]加入 path;
-  不选:跳过 nums[i],进入下一个元素;
-  递归时带一个 startIndex,保证从左到右、不回头。
public class Solution {public IList<IList<int>> res=new List<IList<int>>();public IList<int> path=new List<int>();public IList<IList<int>> FindSubsequences(int[] nums) {BackTracking(nums,0);return res;}public void BackTracking(int[] nums,int startIndex){if(path.Count>=2){res.Add(new List<int>(path));}HashSet<int> hs=new HashSet<int>();for(int i=startIndex;i<nums.Length;i++){if(path.Count>0&&path[path.Count-1]>nums[i]||hs.Contains(nums[i])){continue;}hs.Add(nums[i]);path.Add(nums[i]);BackTracking(nums,i+1);path.RemoveAt(path.Count-1);}}
}46.全排列
| 步骤 | 内容 | 
| 回溯结构 | 逐个选取数字,构造出一个完整路径 | 
| 状态表示 | path 保存当前路径,used[] 表示哪些数被选了 | 
| 终止条件 | 当 path.Count == nums.Length,加入结果集 | 
| 剪枝 | 如果 used[i] == true,跳过当前数字 | 
| 回溯 | 回到上一步时撤销选择(used[i] = false,RemoveAt) | 
1️⃣ 使用回溯法(Backtracking)
-  回溯法用于逐步构造解空间,尝试所有可能路径。 
-  每个位置都尝试一个未使用过的数字,直到构成一个完整排列。 
2️⃣ 路径构建
-  使用 List<int> path表示当前正在构造的排列路径。
-  使用 bool[] used数组标记哪些数字已经被使用,避免重复。
3️⃣ 终止条件
- 当 path.Count == nums.Length时,说明已经选满一个排列,将其加入结果集。
4️⃣ 遍历选择列表
-  遍历 nums中每一个数字:
-  若未被使用,则加入 path; 
-  递归处理下一层; 
-  回溯时撤销选择(移除 path 最后一个元素,并将 used[i] = false)。
5️⃣ 回溯关键点
-  做选择 → 递归 → 撤销选择(回溯) 
-  依赖于系统栈自动回溯到上一层状态 
public class Solution {public IList<IList<int>> res=new List<IList<int>>();public IList<int> path=new List<int>();public IList<IList<int>> Permute(int[] nums) {var used=new bool[nums.Length] ;BackTracking(nums,used);return res;}public void BackTracking(int[] nums,bool[] used){if(path.Count==nums.Length){res.Add(new List<int>(path));return;}for(int i=0;i<nums.Length;i++){if(used[i]) continue;used[i]=true;path.Add(nums[i]);BackTracking(nums,used);used[i]=false;path.RemoveAt(path.Count-1);}}}
