码迷,mamicode.com
首页 > 其他好文 > 详细

【LeetCode】回溯法 backtracking(共39题)

时间:2019-02-14 22:27:11      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:==   暴力   reg   数字   img   通过   blank   beautiful   for   

【10】Regular Expression Matching 

【17】Letter Combinations of a Phone Number 

 

【22】Generate Parentheses (2019年2月13日)

给了一个N,生成N对括号的所有情况的字符串。

n = 3

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

题解:dfs生成。

技术图片
 1 class Solution {
 2 public:
 3     vector<string> generateParenthesis(int n) {
 4         vector<string> res;
 5         string str;
 6         int left = n, right = n;
 7         dfs(str, res, left, right);
 8         return res;
 9     }
10     void dfs(string& str, vector<string>& res, int left, int right) {
11         if (left == 0 && right == 0) {
12             res.push_back(str);
13             return;
14         }
15         if (left <= right && left - 1 >= 0) {
16             str += "(";
17             dfs(str, res, left-1, right);
18             str.pop_back();
19         } 
20         if (left < right && right - 1 >= 0) {
21             str += ")";
22             dfs(str, res, left, right - 1);
23             str.pop_back();
24         }
25     }
26 };
View Code

  

【37】Sudoku Solver 

【39】Combination Sum 

【40】Combination Sum II 

【44】Wildcard Matching 

【46】Permutations (2019年1月23日,谷歌tag复习)(M)

给了一个distinct numbers 的数组,返回所有的排列。

题解:dfs

技术图片
 1 class Solution {
 2 public:
 3     vector<vector<int>> permute(vector<int>& nums) {
 4         dfs(nums);
 5         return ret;
 6     }
 7     vector<int> arr;
 8     vector<vector<int>> ret;
 9     void dfs(const vector<int>& nums) {
10         if (arr.size() == nums.size()) {
11             ret.push_back(arr);
12             return;
13         }
14         for (int i = 0; i < nums.size(); ++i) {
15             set<int> st(arr.begin(), arr.end());
16             if (st.find(nums[i]) != st.end()) { continue; }
17             arr.push_back(nums[i]);
18             dfs(nums);
19             arr.pop_back();
20         }
21         return;
22     }
23 };
View Code

 

【47】Permutations II 

【51】N-Queens 

【52】N-Queens II 

【60】Permutation Sequence 

 

【77】Combinations (2019年1月21日,算法群打卡题)

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.

Input: n = 4, k = 2
Output:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
] 

题解:直接回溯。

技术图片
 1 class Solution {
 2 public:
 3     vector<vector<int>> ret;
 4     vector<vector<int>> combine(int n, int k) {
 5         vector<int> nums;
 6         dfs(nums, 1, n, k);
 7         return ret;
 8     }
 9     void dfs(vector<int>& nums, int cur, const int n, const int k) {
10         if (nums.size() == k) {
11             ret.push_back(nums);
12             return;
13         }
14         for (int i = cur; i <= n; ++i) {
15             nums.push_back(i);
16             dfs(nums, i + 1, n, k);  //这里注意不要写错了。 我有时候会写成 dfs(nums, cur + 1, n, k);
17             nums.pop_back();
18         }
19         return;
20     }
21 };
View Code

 

【78】Subsets (相似的题目见 90 题)

给了一个 distinct 的数组,返回它所有的子集。

题解见位运算专题【78】题,一样的。https://www.cnblogs.com/zhangwanying/p/9886589.html

 

【79】Word Search (2019年1月25日,谷歌tag复习) (Medium)

给了一个单词板和一个单词,四联通,问能不能在板子上面找到这个单词。

题解:backtracking,注意边界哇哭死,没有一次AC

技术图片
 1 class Solution {
 2 public:
 3     bool exist(vector<vector<char>>& board, string word) {
 4         n = board.size(), m = board[0].size();
 5         for (int i = 0; i < n; ++i) {
 6             for (int j = 0; j < m; ++j) {
 7                 if (board[i][j] == word[0]) {
 8                     vector<vector<int>> visit(n, vector<int>(m, 0));
 9                     visit[i][j] = 1;
10                     if (dfs(board, i, j, word, 0, visit)) {
11                         return true;
12                     }
13                 }
14             }
15         }
16         return false;
17     }
18     int n, m;
19     bool dfs(vector<vector<char>>& board, int x, int y, const string word, int cur, vector<vector<int>>& visit) {
20         if (cur + 1 == word.size()) {
21             return true;
22         }
23         for (int i = 0; i < 4; ++i) {
24             int newx = x + dirx[i], newy = y + diry[i];
25             if (newx >= 0 && newx < n && newy >= 0 && newy < m && !visit[newx][newy] && board[newx][newy] == word[cur+1]) {
26                 visit[newx][newy] = 1;
27                 if (dfs(board, newx, newy, word, cur + 1, visit)) {
28                     return true;
29                 }
30                 visit[newx][newy] = 0;
31             }
32         }
33         return false;
34     }
35     int dirx[4] = {-1, 0, 1, 0};
36     int diry[4] = {0, -1, 0, 1};
37 };
View Code

 

89】Gray Code 

【90】Subsets II (算法群,2018年11月21日)

给了一个有重复数字的数组,返回它所有的unique子集。

Input: [1,2,2]
Output:
[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]

题解:回溯法。用set去重,有一点需要注意的是,千万不能每次递归的时候对 现在vector的状态sort一下,不然递归回溯的时候肯定有问题的。

技术图片
 1 class Solution {
 2 public:
 3     vector<vector<int>> subsetsWithDup(vector<int>& nums) {
 4         const int n = nums.size();
 5         vector<vector<int>> ret;
 6         set<vector<int>> stRet;
 7         vector<int> temp;
 8         dfs(nums, stRet, 0, temp);
 9         for (auto ele : stRet) {
10             ret.push_back(ele);
11         }
12         return ret;
13     }
14     void dfs(const vector<int>& nums, set<vector<int>>& st, int cur, vector<int>& temp) {
15         vector<int> t1 = temp;
16         sort(t1.begin(), t1.end());
17         st.insert(t1);
18         if (cur == nums.size()) {return;}
19         for (int i = cur; i < nums.size(); ++i) {
20             temp.push_back(nums[i]);
21             dfs(nums, st, i+1, temp);
22             temp.pop_back();
23         }
24     }
25 };
View Code

 

【93】Restore IP Addresses (2019年2月14日)

给了一个串纯数字的字符串,在字符串里面加‘.’,返回所有合法的ip字符串。

Input: "25525511135"
Output: ["255.255.11.135", "255.255.111.35"] 

题解:backtracking,用一个新的字符串保存当前的ip字符串。ipv4的每一个小段必须是[0, 255],四个小段。 

技术图片
 1 class Solution {
 2 public:
 3     vector<string> restoreIpAddresses(string s) {
 4         const int n = s.size();
 5         vector<string> ret;
 6         if (n == 0) {return ret;}
 7         string temp;
 8         dfs(s, 0, ret, temp, 0);
 9         return ret;
10     }
11     void dfs(const string s, int cur, vector<string>& ret, string& temp, int part) {
12         if (cur == s.size() && part == 4) {
13             ret.push_back(temp);
14             return;
15         }
16         if (part >= 4) {return;}
17         string num;
18         if (s[cur] == 0) {
19             string oriTemp = temp;
20             num = string(1, s[cur]);
21             temp += temp.empty() ? (num) : ("." + num);
22             dfs(s, cur + 1, ret, temp, part + 1);
23             temp = oriTemp;
24         } else {
25             string oriTemp = temp;
26             for (int k = 0; k <= 2; ++k) {
27                 if (cur + k >= s.size()) {break;}
28                 num += s[cur + k];
29                 int inum = stoi(num);
30                 if (inum < 1 || inum > 255) {break;}
31                 temp += temp.empty() ? (num) : ("." + num);
32                 dfs(s, cur + k + 1, ret, temp, part + 1);
33                 temp = oriTemp;
34             }
35         }
36     }
37 };
View Code

  

【126】Word Ladder II 

【131】Palindrome Partitioning 

【140】Word Break II(2018年12月19日,算法群,类似题目 472. DFS专题)

 

【211】Add and Search Word - Data structure design 

【212】Word Search II 

【216】Combination Sum III 

【254】Factor Combinations 

【267】Palindrome Permutation II 

【291】Word Pattern II 

【294】Flip Game II 

【306】Additive Number 

【320】Generalized Abbreviation 

【351】Android Unlock Patterns 

【357】Count Numbers with Unique Digits 

【401】Binary Watch 

【411】Minimum Unique Word Abbreviation 

【425】Word Squares 

【526】Beautiful Arrangement 

【691】Stickers to Spell Word 

【784】Letter Case Permutation 

 

【842】Split Array into Fibonacci Sequence 

给了一个字符串 S,看能不能通过分割字符串,把字符串搞成一个斐波那契数组。(1 <= S.size() <= 200)

题解:就是暴力搜,但是WA吐了快,有几个点要注意,如果是 “000” 这种是可以返回的,返回 [0, 0, 0]。然后如果分割的字符串太长的就要continue,不然你 long long 也没有用,200位肯定超过 long long 了。

技术图片
 1 // WA到吐了,太多情况
 2 class Solution {
 3 public:
 4     vector<int> splitIntoFibonacci(string S) {
 5         vector<int> ans;
 6         if (S.empty()) { return ans; } //S如果是“000”是可以的,所以需要留着dfs.
 7         return dfs(S, ans, 0) ? ans : vector<int>{};
 8     }
 9     bool dfs(string S, vector<int>& ans, int cur_idx) {
10         int n = S.size();
11         if (cur_idx == n) {
12             return ans.size() >= 3 ? true : false;
13         }
14         for (int i = cur_idx; i < n; ++i) {
15             if (ans.size() < 2) {
16                 string strNumber = S.substr(cur_idx, i - cur_idx + 1);
17                 if (strNumber.size() > 10 || strNumber.size() > 1 && strNumber[0] == 0) {continue; }
18                 long long number = stoll(strNumber);
19                 if (number > INT_MAX) {continue;}
20                 ans.push_back(number);
21                 if (dfs(S, ans, i + 1)) {
22                     return true;
23                 }
24                 ans.pop_back();
25             } else {
26                 int ansSize = ans.size();
27                 int num1 = ans.back(), num2 = ans[ansSize - 2];
28                 string strNumber = S.substr(cur_idx, i - cur_idx + 1);
29                 if (strNumber.size() > 10 || strNumber.size() > 1 && strNumber[0] == 0) {continue; }
30                 long long num3 = stoll(strNumber);
31                 if (num3 > INT_MAX) {continue;}
32                 if (num1 + num2 == num3) {
33                     ans.push_back(num3);
34                     if (dfs(S, ans, i + 1)){
35                         return true;
36                     }
37                     ans.pop_back();
38                 }
39             }
40         }
41         return false;
42     }
43 };
View Code

但是好像我的方法巨慢,可以看看discuss怎么求解的。 

【LeetCode】回溯法 backtracking(共39题)

标签:==   暴力   reg   数字   img   通过   blank   beautiful   for   

原文地址:https://www.cnblogs.com/zhangwanying/p/9886305.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!