完全背包|dfs

发布于:2025-09-05 ⋅ 阅读:(28) ⋅ 点赞:(0)

 

 

lc93

复原ip


 方法思路
 
1. 深度优先搜索(DFS):通过递归的方式枚举所有可能的 IP 地址分割点。
2. 有效部分检查:每次递归时,检查当前分割的部分是否为有效整数(在 0 到 255 之间,且无rike前导零)。
3. 递归终止条件:当已经插入了 3 个  .  且处理完整个字符串时,将当前路径加入结果集。
 
解决代码
 
class Solution {
    string s;
    vector<string> ret;
    string path;
    int cnt = 0, n = 0;
public:
    vector<string> restoreIpAddresses(string s) {
        this->s = s;
        n = s.size();
        dfs(0);
        return ret;
    }
    void dfs(int p) {
        if (p == n && cnt == 3) {
            ret.push_back(path);
            return;
        }
        if (cnt > 3) {
            return;
        }
        if (p >= n) {
            return;
        }
        if (s[p] == '0') {
            if (path.empty()) {
                path = "0";
            } else {
                path += ".0";
            }
            cnt++;
            dfs(p + 1);
            if (path.empty()) {
                path = "";
            } else {
                path = path.substr(0, path.size() - 2);
            }
            cnt--;
            return;
        }
        int num = 0;
        for (int i = p; i < n; i++) {
            num = num * 10 + (s[i] - '0');
            if (num > 255) {
                break;
            }
            string temp = path;
            if (path.empty()) {
                path = to_string(num);
            } else {
                path += "." + to_string(num);
            }
            cnt++;
            dfs(i + 1);
            path = temp;
            cnt--;
        }
    }
};
 
 
代码解释
 
1. 类成员变量:
-  s :存储输入的数字字符串。
-  ret :存储所有有效的 IP 地址结果。
-  path :当前正在构建的 IP 地址。
-  cnt :记录已插入的  .  数量。
-  n :输入字符串的长度。
2.  restoreIpAddresses  方法:
- 初始化类成员变量,调用  dfs  方法开始递归搜索。


3.  dfs  方法:
- 终止条件:当处理完整个字符串且已插入 3 个  .  时,将当前路径加入结果集。
- 剪枝条件:如果已插入的  .  数量超过 3 或已处理完字符串但  .  数量不足 3,直接返回。
- 处理前导零:如果当前字符是  0 ,单独处理(因为前导零无效,只能作为单独的部分)。
- 枚举分割点:遍历当前位置到字符串末尾,计算当前分割部分的数值,检查是否在 0 到 255 之间,符合条件则递归处理剩余部分,并在递归后回溯状态。
 
dfs枚举所有可能的分割方式,并在每一步检查分割部分的有效性,确保最终得到的 IP 地址是有效的。

 

lc47.全排列ii

class Solution {
public:
    vector<vector<int>> ret;
    vector<int> path;
    vector<bool> check;

    vector<vector<int>> permuteUnique(vector<int>& nums) 
    {
        //排序
        sort(nums.begin(),nums.end());
        check.resize(nums.size(),false); //init

        dfs(nums);
        return ret;
    }

    void dfs(vector<int>& nums)
    {
        if(path.size()==nums.size())//end
        {
            ret.push_back(path);
            return;
        }

        for(int i=0;i<nums.size();i++)//遍历所有元素
        {
    //legal
            if(check[i]==false && (i==0 || nums[i]!=nums[i-1] || check[i-1]==true))
        {
            check[i]=true;
            path.push_back(nums[i]);

            dfs(nums);

            check[i]=false;//还原
            path.pop_back();

       }   
            
      }
    }
};

 

lc39

 

class Solution {
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        ranges::sort(candidates);
        vector<vector<int>> ans;
        vector<int> path;

        auto dfs = [&](this auto&& dfs, int i, int left) {
            if (left == 0) {
                // 找到一个合法组合
                ans.push_back(path);
                return;
            }

            // 枚举选哪个
            for (int j = i; j < candidates.size() && candidates[j] <= left; j++) {
                path.push_back(candidates[j]);
                dfs(j, left - candidates[j]);


                path.pop_back(); // 恢复现场
            }
        };

        dfs(0, target);
        return ans;
    }
};
 

 


网站公告

今日签到

点亮在社区的每一天
去签到