zoukankan      html  css  js  c++  java
  • LeetCode39/40/22/77/17/401/78/51/46/47/79 11道回溯题(Backtracking)

    LeetCode 39

     1 class Solution {
     2 public:
     3     void dfs(int dep, int maxDep, vector<int>& cand, int target)
     4 {
     5     if (target < 0)return;
     6     if (dep == maxDep)
     7     {
     8         if (target == 0)//到达尾部且等于target
     9         {
    10               vector<int> temp;
    11               for (int i = 0; i < maxDep; i++)
    12               {
    13                 for (int j = 0; j < num[i]; j++)
    14                     temp.push_back(cand[i]);
    15               }
    16                 ret.push_back(temp);
    17             }
    18             return;
    19         }
    20         for (int i = 0; i <= target / cand[dep]; i++)//枚举合适的情况
    21         {
    22             num[dep] = i;
    23             dfs(dep + 1, maxDep, cand, target - i*cand[dep]);
    24         }
    25 }
    26 vector<vector<int>> combinationSum(vector<int>& candidates, int target) 
    27 {
    28     int n = candidates.size();
    29     if (n == 0)return ret;
    30     sort(candidates.begin(), candidates.end());
    31     num.resize(n);
    32     ret.clear();
    33     dfs(0, n, candidates, target);
    34     return ret;
    35 
    36 }
    37 private:
    38     vector<vector<int>> ret;//返回的结果
    39     vector<int> num;//用来存储每个数字的次数
    40 };

      LeetCode 40

     1 class Solution {
     2 public:
     3 void dfs(int dep, int maxDep, vector<int>& cand, int target)
     4 {
     5     if (target < 0)return;
     6     if (dep == maxDep)
     7     {
     8         if (target == 0)
     9         {
    10               vector<int> temp;
    11               for (int i = 0; i < maxDep; i++)
    12               {
    13                 for (int j = 0; j < num[i]; j++)
    14                     temp.push_back(cand[i]);
    15               }
    16                 res.insert(temp);
    17             }
    18             return;
    19         }
    20         for (int i = 0; i<=1; i++)
    21         {
    22             num[dep] = i;
    23             dfs(dep + 1, maxDep, cand, target - i*cand[dep]);
    24         }
    25 }
    26 vector<vector<int>> combinationSum2(vector<int>& candidates, int target) 
    27 {
    28     int n = candidates.size();
    29     if (n == 0)return ret;
    30     sort(candidates.begin(), candidates.end());
    31     num.resize(n);
    32     ret.clear();
    33     dfs(0, n, candidates, target);
    34     set<vector<int>>::iterator it= res.begin();
    35     for (;it!=res.end();it++)
    36     {
    37         ret.push_back(*it);
    38     }
    39     return ret;
    40 
    41 }
    42 
    43 private:
    44     vector<vector<int>> ret;
    45     set<vector<int>> res;
    46     vector<int> num;
    47 };

     LeetCode 22

    backtracking函数书写的一般规则:

    (1)函数参数一般要包括位置或者其它(如本题中的还可以剩余左括号个数及左边有多少个左括号没有关闭),这些都是为函数内容作为判断条件,要选择好。

    (2)函数开头是函数终止条件(如本题中已经没有左括号可以使用了,故return),并将结束得到的一个结果(元素可以不取的话,则将临时结果变量作为函数的参数<如subset>,每个元素都要取一个结果,则作为类成员)放入result中

     (3)就是函数的后半部分,为递归,函数该位置可以放那些元素(循环),每种元素放入后递归下一个位置的元素,当然包括参数的变化。

    (1)参数:pos:迭代位置,共有2*n个元素,表示迭代到第几个位置了, left表示左边已经有多少个左括号没有关闭,当left==0时就不能迭代右括号了,remain表示还可以加入左括号的个数,当remain==0的时候,就不能迭代左括号了。

    (2)终止条件:当remain==0时,只能加入右括号了,并将这一结果加入最后的结果中

    (3)每个位置都只能放入左右括号两种情况,分别取这两种情况,然后进行下一次迭代。

     1 class Solution {
     2 public:
     3     void dfs(int pos, string &str, int left, int remain, int n){   // left表示左边有多少个左括号没有关闭
     4         if(remain == 0){  // 左括号使用完毕  故全部为右括号
     5             for(int i = pos; i < 2*n; i++)
     6                 str[i] = ')';
     7             result.push_back(str);
     8             return;
     9         }
    10         
    11         if(remain > 0){             // remain!=0 说明还可以使用左括号
    12             str[pos] = '(';
    13             dfs(pos+1, str, left+1, remain-1, n);
    14         }
    15         if(left != 0){               // left!=0 表示左边还有左括号没有关闭,故可以使用)
    16             str[pos] = ')';
    17             dfs(pos+1, str, left-1, remain, n);
    18         }
    19     }
    20     vector<string> generateParenthesis(int n) {
    21         string str;
    22         str.resize(2*n);
    23         dfs(0, str, 0, n, n);
    24         return result;
    25         
    26     }
    27 private:
    28     vector<string> result;
    29 };

     Leetcode 77

     1 class Solution {
     2 private:
     3     vector<vector<int>> result;
     4     vector<int> tmp;
     5 public:
     6     void dfs(int dep, const int &n, int k, int count)
     7     {
     8         if (count == k)
     9         {
    10             result.push_back(tmp);
    11             return;
    12         }
    13         if (dep < n - k + count)
    14         {
    15             dfs(dep + 1, n, k, count);//不取当前数
    16         }
    17         tmp[count] = dep + 1;         //取当前数
    18         dfs(dep + 1, n, k, count+1);
    19         
    20     }
    21     vector<vector<int>> combine(int n, int k)
    22     {
    23         if (k>n)k = n;
    24         tmp.resize(k);
    25         dfs(0, n, k, 0);
    26         return result;
    27     }
    28 
    29 };

     LeetCode 17

     1 string NumToStr[10] = {"", "","abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; 
     2 class Solution {
     3 private:
     4     string str;
     5     vector<string> result;
     6 public:
     7     int charToInt(char c)
     8     {
     9         int i;
    10         stringstream ss;
    11         ss << c;
    12         ss >> i;
    13         return i;
    14     }
    15     void dfs(int dep, int maxDep, const string &digits)
    16     {
    17         if (dep == maxDep)
    18         {
    19             result.push_back(str);
    20         }
    21         int index = charToInt(digits[dep]);
    22         for (int i = 0; i < NumToStr[index].size(); i++)
    23         {
    24             str[dep] = NumToStr[index][i];
    25             dfs(dep+1,maxDep,digits);
    26         }
    27     }
    28 
    29     vector<string> letterCombinations(string digits)
    30     {
    31         int n = digits.size();
    32         if (n == 0)return result;
    33         str.resize(n);
    34         dfs(0,n,digits);
    35         return result;
    36     }
    37 };

     LeetCode 401

     1 class Solution {
     2 vector<int> hour = { 1, 2, 4, 8 }, minute = {1,2,4,8,16,32};
     3 public:
     4     void helper(vector<string> & res, pair<int, int> time, int num, int start_point)
     5     {
     6         if (num == 0)
     7         {
     8             if (time.second < 10)
     9                 res.push_back(to_string(time.first) + ":0" + to_string(time.second));
    10             else
    11                 res.push_back(to_string(time.first) + ":" + to_string(time.second));
    12             return;
    13         }
    14         for (int i = start_point; i < hour.size() + minute.size(); i++)
    15         {
    16             if (i < hour.size())
    17             {
    18                 time.first += hour[i];
    19                 if (time.first < 12)
    20                     helper(res, time, num - 1, i + 1);
    21                 time.first -= hour[i];
    22             }
    23             else
    24             {
    25                 time.second += minute[i - hour.size()];
    26                 if (time.second < 60)
    27                     helper(res,time,num-1,i+1);
    28                 time.second -= minute[i - hour.size()];
    29             }
    30         }
    31     }
    32     vector<string> readBinaryWatch(int num)
    33     {
    34         vector<string> res;
    35         helper(res,make_pair(0,0),num,0);
    36         return res;
    37     }
    38     
    39 };

    LeetCode 78

     1 class Solution {
     2 public:
     3     vector<int>ans;
     4     vector<vector<int>> res;
     5     vector<vector<int>> subsets(vector<int>& nums) {
     6         if(nums.empty())return res;
     7         sort(nums.begin(),nums.end());
     8         dfs(0,ans,nums);
     9         return res;
    10     }
    11     void dfs(int k,vector<int> ans, vector<int> nums)
    12     {
    13         res.push_back(ans);
    14         for(int i=k;i<nums.size();i++)
    15         {
    16             ans.push_back(nums[i]);
    17             dfs(i+1,ans,nums);
    18             ans.pop_back();
    19         }
    20     }
    21 };

    LeetCode 51

     1 class Solution {
     2 private:
     3     vector<vector<string> > res;
     4 public:
     5     vector<vector<string> > solveNQueens(int n) {
     6         vector<string>cur(n, string(n,'.'));
     7         helper(cur, 0);
     8         return res;
     9     }
    10     void helper(vector<string> &cur, int row)
    11     {
    12         if(row == cur.size())
    13         {
    14             res.push_back(cur);
    15             return;
    16         }
    17         for(int col = 0; col < cur.size(); col++)
    18             if(isValid(cur, row, col))
    19             {
    20                 cur[row][col] = 'Q';
    21                 helper(cur, row+1);
    22                 cur[row][col] = '.';
    23             }
    24     }
    25      
    26     //判断在cur[row][col]位置放一个皇后,是否是合法的状态
    27     //已经保证了每行一个皇后,只需要判断列是否合法以及对角线是否合法。
    28     bool isValid(vector<string> &cur, int row, int col)
    29     {
    30         //
    31         for(int i = 0; i < row; i++)
    32             if(cur[i][col] == 'Q')return false;
    33         //右对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
    34         for(int i = row-1, j=col-1; i >= 0 && j >= 0; i--,j--)
    35             if(cur[i][j] == 'Q')return false;
    36         //左对角线(只需要判断对角线上半部分,因为后面的行还没有开始放置)
    37         for(int i = row-1, j=col+1; i >= 0 && j < cur.size(); i--,j++)
    38             if(cur[i][j] == 'Q')return false;
    39         return true;
    40     }
    41 };

    LeetCode 46

     1 class Solution {
     2 private:
     3     vector<vector<int>> result;
     4     vector<int> visited;
     5 public:
     6     void dfs(int st, int n, vector<int>& v, vector<int>& nums)
     7     {
     8         if (st == n)
     9         {
    10             result.push_back(v);
    11             return;
    12         }
    13         for (int i = 0; i < n; i++)
    14         {
    15             if (visited[i] != 1)
    16             {
    17                 visited[i] = 1;
    18                 v.push_back(nums[i]);
    19                 dfs(st + 1, n,v,nums);
    20                 v.pop_back();
    21                 visited[i] = 0;
    22             }
    23         }
    24     }
    25     vector<vector<int>> permute(vector<int>& nums)
    26     {
    27         int num = nums.size();
    28         visited.resize(num);
    29         vector<int> tmp;
    30         dfs(0,num,tmp,nums);
    31         return result;
    32     }
    33 
    34 };

     LeetCode 47

     1 class Solution {
     2 private:
     3     vector<vector<int>> result;
     4     vector<int> tmpResult;
     5     vector<int> count;
     6 public:
     7     void dfs(int dep, int maxDep, vector<int>& num, vector<int> visited)
     8     {
     9         if (dep == maxDep)
    10         {
    11             result.push_back(tmpResult);
    12             return;
    13         }
    14         for (int i = 0; i < num.size(); i++)
    15         {
    16             if (i == 0)count[dep] = 0;
    17             if (!visited[i])
    18             {
    19                 count[dep]++;
    20                 if (count[dep]>1 && tmpResult[dep] == num[i])continue; 
    21                 // 每个位置第二次选数时和第一次一样则continue
    22                 visited[i] = 1;             // 每个位置第二次选择的数时和第一次不一样  
    23                 tmpResult[dep] = num[i];
    24                 dfs(dep + 1, maxDep, num, visited);
    25                 visited[i] = 0;
    26             }
    27         }
    28     }
    29     vector<vector<int>> permuteUnique(vector<int> &num)
    30     {
    31         sort(num.begin(), num.end());
    32         tmpResult.resize(num.size());
    33         count.resize(num.size());
    34         vector<int> visited;
    35         visited.resize(num.size());
    36         dfs(0, num.size(), num, visited);
    37         return result;
    38     }
    39 };

    LeetCode 79

     1 class Solution {
     2 public:
     3     bool dfs(int xi, int yi, string &word, int index, vector<vector<char> > &board, const int &m, const int &n, int **visited){
     4         visited[xi][yi] = 1;        // 该结点已经访问过了
     5         if(index + 1 < word.size()){
     6             if(xi-1 >= 0 && visited[xi-1][yi]==0 && board[xi-1][yi] == word[index+1]){
     7                 if(dfs(xi-1, yi, word, index+1, board, m, n, visited))return true;   //深度遍历
     8                 visited[xi-1][yi] = 0;      // 这条路行不通 设为未访问 以不影响下面的遍历
     9             }
    10             if(xi+1 <m && visited[xi+1][yi]==0 && board[xi+1][yi] == word[index+1]){
    11                 if(dfs(xi+1, yi, word, index+1, board, m, n, visited))return true;
    12                 visited[xi+1][yi] = 0;
    13             }
    14             if(yi-1 >= 0 && visited[xi][yi-1]==0 && board[xi][yi-1] == word[index+1]){
    15                 if(dfs(xi, yi-1, word, index+1, board, m, n,visited)) return true;
    16                 visited[xi][yi-1] = 0;
    17             }
    18             if(yi+1 < n && visited[xi][yi+1]==0 && board[xi][yi+1] == word[index+1]){
    19                 if(dfs(xi, yi+1, word, index+1, board, m, n,visited)) return true;
    20                 visited[xi][yi+1] = 0;
    21             }
    22             return false;
    23         }else return true;
    24     }
    25     
    26     void initVisited(int ** visited, const int &m, const int &n){
    27         for(int i = 0; i < m; i++)
    28             memset(visited[i], 0, sizeof(int)*n);
    29     }
    30     bool exist(vector<vector<char> > &board, string word) {
    31         int m = board.size();
    32         int n = board[0].size();
    33         int **visited = new int*[m];
    34         for(int i = 0; i < m; i++)
    35             visited[i] = new int[n];
    36         
    37         for(int i = 0; i < m; i++){   // 找到其中的i和j
    38             for(int j = 0; j < n; j++){
    39                 if(word[0] == board[i][j]){
    40                     initVisited(visited, m, n);
    41                     if(dfs(i, j, word, 0, board, m, n,visited)) return true;
    42                 }
    43             }
    44         }
    45         for(int i = 0; i < m; i++)
    46             delete []visited[i];
    47         delete []visited;
    48         return false;
    49     }
    50 };
  • 相关阅读:
    2013年元旦新年好
    2012第52周三阴雨
    2013第1周四雪
    2013年元旦新年好
    2013第1周三阴冷
    2012第52周日晴冷
    2012周六补记
    PHP怎么调用其他类的方法
    面向对象复习笔记(一)
    Laravel 引入自定义类库或第三方类库
  • 原文地址:https://www.cnblogs.com/demian/p/5933684.html
Copyright © 2011-2022 走看看