赞
踩
<按出题频率排列>
大佬回溯算法详解:
解题思路:
如下
/* 递归每一种字符串加入即可 左右括号数量至少有一个不为0,这种情况下只有左括号能为0,右括号必不可能为0,因为最后一个括号一定是右括号 */ class Solution { public: void addParenthesis(vector<string>& coll, string s, int l, int r){ if(l == 0 && r == 0){ coll.push_back(s); return; } if(l == 0){ addParenthesis(coll, s + ")", l, r - 1); } else if(l < r){ addParenthesis(coll, s + "(", l - 1, r); addParenthesis(coll, s + ")", l, r - 1); } else if(l == r){ addParenthesis(coll, s + "(", l - 1, r); } } vector<string> generateParenthesis(int n) { string s; vector<string> res; addParenthesis(res, s, n, n); return res; } };
解题思路:
见顶部回溯算法详解
class Solution { public: //depth表示树的总深度,idex表示当前深度 void dfs(vector<vector<int>> &res, vector<int> &used, vector<int> &nums, vector<int> &s, int &depth, int idex){ if(depth < idex) res.push_back(s); for(int i = 0; i < depth; i++){ if(used[i] == 0){ s.push_back(nums[i]); used[i] = 1;//标记已经使用 dfs(res, used, nums, s, depth, idex + 1); s.erase(s.end() - 1); used[i] = 0; } } } vector<vector<int>> permute(vector<int>& nums) { vector<vector<int>> res; vector<int> s; int depth = nums.size(); if(depth == 0) return res; vector<int> used(depth, 0);//状态标记数组 dfs(res, used, nums, s, depth, 1); return res; } };
解题思路:
如下
/* 回溯 + 贪心 step1: 将给定数组进行排序 step2: 先一直加入当前位置最大值,直至等于target或者超过target step2.1: 等于target: 加入该种情况,将该数字标记为已使用(即pos + 1, 到下一个比当前值小的值),返回上一级 step2.2: 大于target: 将数字标记为已使用,返回上一级 */ class Solution { public: void dfs(vector<vector<int>>& res, vector<int>& candidates, int& pos, vector<int>& s, int target, int& sum){ if(sum == target){ res.push_back(s); return; } else if(sum > target) return; //保存传入位置,离开此次循环时需要重置回初始环境 int tmp = pos; for(int i = pos; i < candidates.size(); i++){ s.push_back(candidates[i]); dfs(res, candidates, pos, s, target, sum += candidates[i]); pos++; s.erase(s.end() - 1); sum -= candidates[i]; } //重置为初始环境 pos = tmp; } vector<vector<int>> combinationSum(vector<int>& candidates, int target) { vector<vector<int>> res; vector<int> s; sort(candidates.begin(), candidates.end(), greater<int>()); int sum = 0, pos = 0; dfs(res, candidates, pos, s, target, sum); return res; } };
解题思路:
很简单的回溯算法思路
/* 回溯算法即可,很简单的一道题 */ class Solution { public: vector<string> al = {"abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"}; void dfs(vector<string>& res, string& digits, int posOfDig, int posInside,string& s){ if(posOfDig == digits.size()){ res.push_back(s); return; } int num = digits[posOfDig] - '0'; int digSize = al[num - 2].size(); for(int i = posInside; i < digSize; i++){ s.push_back(al[num - 2][i]); if(posOfDig < digits.size()){ dfs(res, digits, posOfDig + 1, 0, s); } s.erase(s.end() - 1); } } vector<string> letterCombinations(string digits) { vector<string> res; if(digits.size() == 0) return res; string s; dfs(res, digits, 0, 0, s); return res; } };
HARD: SKIP
解题思路:
如下
//包含所有无序的版本 class Solution { public: void dfs(vector<vector<int>>& res, vector<int>& nums, vector<int>& used, vector<int>& add){ if(add.size() == nums.size()) return; for(int i = 0; i < nums.size(); i++){ if(used[i] == 0){ add.push_back(nums[i]); res.push_back(add); used[i] = 1; dfs(res, nums, used, add); used[i] = 0; add.erase(add.end() - 1); } } } vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>> res; vector<int> empty; res.push_back(empty); vector<int> used(nums.size(), 0); vector<int> add; dfs(res, nums, used, add); return res; } };
//顺序版本 class Solution { public: void dfs(vector<vector<int>>& res, vector<int>& nums, int& pos, vector<int>& add){ if(pos == nums.size()) return; int tmp = pos; for(int i = pos; i < nums.size(); i++){ add.push_back(nums[i]); res.push_back(add); dfs(res, nums, pos += 1, add); add.erase(add.end() - 1); } pos = tmp; } vector<vector<int>> subsets(vector<int>& nums) { vector<vector<int>> res; vector<int> empty; res.push_back(empty); vector<int> add; int pos = 0; dfs(res, nums, pos, add); return res; } };
解题思路:
class Solution { public: bool dfsCheck(vector<vector<char>>& board, string& word, int posOfWord, vector<vector<int>>& used, int x, int y){ //检测数组越界 if(x < 0 || x == board.size() || y < 0 || y == board[0].size()) return false; //检测对应字母是否已经被使用或者不正确 if(used[x][y] == 1 || board[x][y] != word[posOfWord]) return false; used[x][y] = 1; //检测是否到了最后一位 if(posOfWord == word.size() - 1) return true; bool ret = dfsCheck(board, word, posOfWord + 1, used, x - 1, y) || dfsCheck(board, word, posOfWord + 1, used, x + 1, y) || dfsCheck(board, word, posOfWord + 1, used, x, y - 1) || dfsCheck(board, word, posOfWord + 1, used, x, y + 1); if(!ret) used[x][y] = 0; return ret; } bool exist(vector<vector<char>>& board, string word) { vector<int> tmp(board[0].size(), 0); vector<vector<int>> used(board.size(), tmp);//设置标记 int num1 = board.size(); int num2 = board[0].size(); for(int i = 0; i < board.size(); i++){ for(int j = 0; j < board[0].size(); j++){ if(dfsCheck(board, word, 0, used, i, j)) return true; } } return false; } };
解题思路:
回溯非最优思路
class Solution { public: //若为减号,mul为-1,若为加号,mul为+1 //sum为表达式的和 //count为满足要求的数量 void dfs(vector<int>& nums, int& target, int sum, int posOfNums, int mul, int& count){ sum += mul * nums[posOfNums]; if(posOfNums == nums.size() - 1){ if(sum == target) count++; return; } dfs(nums, target, sum, posOfNums + 1, 1, count); dfs(nums, target, sum, posOfNums + 1, -1, count); } int findTargetSumWays(vector<int>& nums, int target) { int count = 0; dfs(nums, target, 0, 0, 1, count); dfs(nums, target, 0, 0, -1, count); return count; } };
动态规划思路:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。