JHHK

欢迎来到我的个人网站
行者常至 为者常成

【题目】8、DFS

目录

17. 电话号码的字母组合

题目描述

17. 电话号码的字母组合
 
 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。
 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。


 示例:
 输入:"23"
 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
 
 说明:
 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。

 
 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目实现

class Solution {
    
    //构造一个char[][]
    vector<vector<char>> lettersArray = {
        {'a', 'b', 'c'}, {'d', 'e', 'f'}, {'g', 'h', 'i'},
        {'j', 'k', 'l'}, {'m', 'n', 'o'}, {'p', 'q', 'r', 's'},
        {'t', 'u', 'v'}, {'w', 'x', 'y', 'z'}
    };
    
    //用来存储每一层选择的字母
    string cs;
    
    //用来存储最终的结果
    vector<string>list;
    
    //深度优先搜索
    void dfs(int idx,string digits){
        //已经进入到最后一层了,不能再往下搜索
        if (idx == digits.length()) {
            // 得到了一个正确的解
            list.push_back(cs);
            return;
        }
        
        // 先枚举这一层可以做的所有选择
        vector<char> chars = lettersArray[digits[idx] - '2'];
        for (char c : chars) {
            cs[idx] = c;
            dfs(idx+1, digits);
            //来到这里,回溯
        }
    }

public:
    vector<string> letterCombinations(string digits) {
        if (digits.length()<=0) return vector<string>();
        //初始化list
        list = vector<string>();
        
        //初始化cs
        cs = string(digits.length(),' ');
        
        //调用dfs
        dfs(0, digits);
        
        return list;
    }
};

46. 全排列

题目描述

 46. 全排列
 
 给定一个 没有重复 数字的序列,返回其所有可能的全排列。

 示例:
 输入: [1,2,3]
 输出:
 [
   [1,2,3],
   [1,3,2],
   [2,1,3],
   [2,3,1],
   [3,1,2],
   [3,2,1]
 ]

 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/permutations
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处

题目实现 - 方式一

class Solution1 {

    void dfs(int idx,
             vector<int>& nums,
             vector<int>& levelInts,
             vector<vector<int>>& result){
        
        if (idx == nums.size()) {
            result.push_back(levelInts);
            return;
        }
        
        
        for (int i = 0; i<nums.size(); i++) {
            //如果已经被使用了continue
            if(count(levelInts.begin(), levelInts.end(), nums[i])) continue;
            
            levelInts[idx] = nums[i];
            
            dfs(idx+1, nums,levelInts,result);
            
            //还原现场
            levelInts[idx] = INT8_MAX;
        }
        
    }

public:
    vector<vector<int>> permute(vector<int>& nums) {
        if (nums.size() == 0) return  vector<vector<int>>();

        //存放每一层的选择
        vector<int> levelInts =  vector<int>(nums.size(),INT8_MAX);
        
        //存放最终的结果
        vector<vector<int>> result = vector<vector<int>>();

        //调用dfs
        dfs(0, nums,levelInts,result);

        return result;
    }
};

题目实现 - 方式二

class Solution2 {

    void dfs(int idx,vector<int>& nums,
             vector<int>& levelInts,
             vector<vector<int>>& result,
             vector<bool>& used){
        
        if (idx == nums.size()) {
            result.push_back(levelInts);
            return;
        }
        
        for (int i = 0; i<nums.size(); i++) {
            //如果已经被使用了continue
            if(used[i]) continue;
            
            
            levelInts[idx] = nums[i];
            
            //标记已经被使用
            used[i] = true;
            
            dfs(idx+1, nums,levelInts,result,used);
            
            //还原现场
            used[i] = false;
        }
    }

public:
    vector<vector<int>> permute(vector<int>& nums) {
        if (nums.size() == 0) return  vector<vector<int>>();

        //存放每一层的选择
        vector<int> levelInts =  vector<int>(nums.size(),0);
        
        //存放是否被使用过
        vector<bool>  used = vector<bool>(nums.size(),false);

        //存放最终的结果
        vector<vector<int>> result = vector<vector<int>>();

        //调用dfs
        dfs(0, nums,levelInts,result,used);

        return result;
    }
};

题目实现 - 方式三

class Solution {

    void dfs(int idx,vector<int>& nums,
             vector<int>& levelInts,
             vector<vector<int>>& result){
        
        if (idx == nums.size()) {
            int size = (int)nums.size();
            for (int i = 0;i<size;i++) {
                levelInts[i] = nums[i];
            }
            result.push_back(levelInts);
            return;
        }
        
        for (int i = idx; i<nums.size(); i++) {
            swap(nums, idx,i);
            dfs(idx+1, nums,levelInts,result);
            //还原现场
            swap(nums, idx,i);
        }
    }
    
    
    //交换两个数据
    void swap(vector<int>& nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

public:
    vector<vector<int>> permute(vector<int>& nums) {
        if (nums.size() == 0) return  vector<vector<int>>();

        //存放每一层的选择
        vector<int> levelInts =  vector<int>(nums.size());
        
        //存放最终的结果
        vector<vector<int>> result = vector<vector<int>>();

        //调用dfs
        dfs(0, nums,levelInts,result);

        return result;
    }
};

47. 全排列 II

题目描述

47. 全排列 II
 
 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

  

 示例 1:
 输入:nums = [1,1,2]
 输出:
 [[1,1,2],
  [1,2,1],
  [2,1,1]]
 
 示例 2:
 输入: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 <= 8
 -10 <= nums[i] <= 10

 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/permutations-ii
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目实现

class Solution {

    void dfs(int idx,vector<int>& nums,
             vector<int>& levelInts,
             vector<vector<int>>& result){
        
        if (idx == nums.size()) {
            int size = (int)nums.size();
            for (int i = 0;i<size;i++) {
                levelInts[i] = nums[i];
            }
            result.push_back(levelInts);
            return;
        }
        
        for (int i = idx; i<nums.size(); i++) {
            // 要保证一个数字在idx位置只会出现一次
            if (isRepeat(nums, idx, i)) continue;

            swap(nums, idx,i);
            dfs(idx+1, nums,levelInts,result);
            //还原现场
            swap(nums, idx,i);
        }
    }
    
    bool isRepeat(vector<int>&nums,int idx,int i){
        for (int j = idx; j < i; j++) {
            if (nums[j] == nums[i]) return true;
        }
        return false;
    }
    
    //交换两个数据
    void swap(vector<int>& nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

public:
    vector<vector<int>> permuteUnique(vector<int>& nums) {
        if (nums.size() == 0) return  vector<vector<int>>();

        //存放每一层的选择
        vector<int> levelInts =  vector<int>(nums.size());
        
        //存放最终的结果
        vector<vector<int>> result = vector<vector<int>>();

        //调用dfs
        dfs(0, nums,levelInts,result);

        return result;
    }
};

22. 括号生成

题目描述

22. 括号生成
 
 数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

 示例:
 输入:n = 3
 输出:[
        "((()))",
        "(()())",
        "(())()",
        "()(())",
        "()()()"
      ]

 
 来源:力扣(LeetCode)
 链接:https://leetcode-cn.com/problems/generate-parentheses
 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目实现

class Solution {
    /**
     * @param idx 搜索的层号
     * @param leftRemain 左括号的剩余数量
     * @param rightRemain 右括号的剩余数量
     * @param str 用来存放每一层的选择
     */
    
    void dfs(int idx,int leftRemain,int rightRemain,
             string& str,vector<string>&list){
        
        if (idx == str.length()){
            list.push_back(str);
            return;
        }
        
        
        // 枚举这一层所有可能的选择
        // 选择一种可能之后,进入下一层搜索
        
        // 什么情况可以选择左括号?左括号的数量 > 0
        // 选择左括号,然后进入下一层搜索
        if (leftRemain > 0) {
            str[idx] = '(';
            dfs(idx+1, leftRemain-1, rightRemain, str, list);
        }
        
        // 当左括号、右括号的数量一样时,只能选择左括号
        // 什么情况可以选择右括号?(右括号的数量 > 0) && (右括号的数量 != 左括号的数量)
        // 选择右括号,然后进入下一层搜索
        if (rightRemain > 0 && leftRemain != rightRemain) {
            str[idx] = ')';
            dfs(idx+1, leftRemain, rightRemain-1, str, list);
        }
    }
    
public:
    vector<string> generateParenthesis(int n) {
        vector<string> list = vector<string>();
        if (n < 0) return list;
        
        string str = string(n<<1,' ');
        dfs(0, n, n,str,list);
        
        return list;        
    }
};

行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.