leetcode回溯法专栏(详解)

leetcode回溯法专栏

  • 预备知识(递归)
  • 回溯法
    • LeetCode 17 电话号码的字母组合
      • code1
      • code2
    • LeetCode 39 组合总和
    • LeetCode 40 组合总和2
    • LeetCode 46 全排列
      • 图解
      • code1
      • code2
    • leetcode 78. 子集
      • code1
      • code2
    • LeetCode 79 单词搜索
    • LeetCode 90 子集2
    • LeetCode 93 复原IP地址
    • LeetCode 131 分隔回文串

预备知识(递归)

#include
#include

using namespace std;

class Solution {
public:
	void generation(int i, vector& nums, vector& item, vector>& result) {
		if (i>=nums.size()) {
			return;	
		}
		item.push_back(nums[i]);
		result.push_back(item);
		generation(i+1, nums, item, result);
	}
};
int main() {
	vector nums;
	nums.push_back(1);
	nums.push_back(2);
	nums.push_back(3);
	vector item;
	vector> result;
	Solution().generation(0, nums, item, result);
	for (int i = 0; i < result.size(); i++) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << result[i][j] << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;

}

回溯法

LeetCode 17 电话号码的字母组合

code1

#include
#include
#include

using namespace std;

class Solution {
public:
	vector letterCombinations(string digits) {
		if (digits.empty()) return {};
		vector res;
		vector dict{ " ", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
		letterCombinationsDFS(digits, dict, 0, "", res);
		return res;
	}
	void letterCombinationsDFS(string& digits, vector& dict, int level, string out, vector& res) {
		if (level == digits.size()) { res.push_back(out); return; }
		string str = dict[digits[level] - '0'];//找到数字字符对应的字母
		for (int i = 0; i < str.size(); ++i) {
			letterCombinationsDFS(digits, dict, level + 1, out + str[i], res);
		}
	}
};
int main() {
	vector res = Solution().letterCombinations("234");
	for (int i = 0; i < res.size(); i++)
		cout << res[i] << endl;
	system("pause");
	return 0;
}

code2

#include
#include
#include
#include

using namespace std;

class Solution {
private:
	vector res;
	const string letterMap[10] = {
		" ",
		"",
		"abc",
		"def",
		"ghi",
		"jkl",
		"mno",
		"pqrs",
		"tuv",
		"wxyz"
	};
	void findCombinations(const string& digits, int index, const string& s) {
		if (index == digits.size()) {
			res.push_back(s); 
			return;
		}
			
		char c = digits[index];
		assert( c >= '0' && c <= '9' && c != '1');
		string letters = letterMap[c - '0'];
		for (int i = 0; i < letters.size(); ++i) {
			findCombinations(digits,index+1,s+letters[i]);
		}
	}
public:
	vector letterCombinations(string digits) {
		res.clear();
		if (digits == "") return res;
		findCombinations(digits,0,"");
		return res;
	}
};
int main() {
	string digits = "23";
	vector res = Solution().letterCombinations(digits);
	for (int i = 0; i < res.size(); ++i) {
		cout << res[i] << endl;
	}
	system("pause");
	return 0;
}

LeetCode 39 组合总和

#include
#include
#include

using namespace std;

class Solution {
public:
	vector> combinationSum(vector& candidates, int target) {
		vector> res;
		vector out;
		combinationSumDFS(candidates, target, 0, out, res);
		return res;
	}
	void combinationSumDFS(vector& candidates, int target, int start, vector& out, vector>& res) {
		if (target < 0) return;
		if (target == 0) { res.push_back(out); return; }
		for (int i = start; i < candidates.size(); ++i) {
			out.push_back(candidates[i]);
			combinationSumDFS(candidates, target - candidates[i], i, out, res);
			out.pop_back();
		}
	}
};
int main() {
	vector candidates = {2,3,6,7};
	int target = 7;
	vector> result = Solution().combinationSum(candidates, target);
	for (int i = 0; i < result.size(); i++) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << result[i][j] << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

LeetCode 40 组合总和2

#include
#include
#include

using namespace std;

class Solution {
public:
	vector > combinationSum2(vector &num, int target) {
		vector > res;
		vector out;
		sort(num.begin(), num.end());
		combinationSum2DFS(num, target, 0, out, res);
		return res;
	}
	void combinationSum2DFS(vector &num, int target, int start, vector &out, vector > &res) {
		if (target < 0) 
			return;
		else if (target == 0) res.push_back(out);
		else {
			for (int i = start; i < num.size(); ++i) {
				if (i > start && num[i] == num[i - 1]) 
					continue;
				out.push_back(num[i]);
				combinationSum2DFS(num, target - num[i], i, out, res);
				out.pop_back();
			}
		}
	}
};
int main() {
	vector candidates = {2,2,2,2,1,7};
	int target = 8;
	vector> result = Solution().combinationSum2(candidates, target);
	for (int i = 0; i < result.size(); i++) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << result[i][j] << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

LeetCode 46 全排列

图解

leetcode回溯法专栏(详解)_第1张图片

code1

#include
#include

using namespace std;

class Solution {
public:
	vector> permute(vector& num) {
		vector> res;
		permuteDFS(num, 0, res);
		return res;
	}
	void permuteDFS(vector& num, int start, vector>& res) {
		if (start >= num.size()) res.push_back(num);
		for (int i = start; i < num.size(); ++i) {
			swap(num[start], num[i]);
			permuteDFS(num, start + 1, res);
			swap(num[start], num[i]);
		}
	}
};
int main() {
	vector num{1,2,3};
	vector> res = Solution().permute(num);
	for (int i = 0; i < res.size(); i++) {
		for (int j = 0; j < res[i].size(); j++)
			cout << res[i][j];
		cout << endl;
	}	
	system("pause");
	return 0;
}

code2

#include 
#include 
#include 

using namespace std;

class Solution {
private:
	vector> res;
	vector used;
	void generatePermutation(const vector& nums, int index, vector& p) {
		if (index == nums.size()) { 
			res.push_back(p); 
			return; 
		}
		for (int i = 0; i < nums.size(); i++) {
			if (!used[i]) {
				p.push_back(nums[i]);
				used[i] = true;
				generatePermutation(nums, index + 1, p);
				p.pop_back();
				used[i] = false;
			}
		}
		return;
	}
public:
	vector> permute(vector& nums) {
		res.clear();
		if (nums.size() == 0)
			return res;
		used = vector(nums.size(), false);
		vector p;
		generatePermutation(nums, 0, p);
		return res;
	}
};
int main() {
	vector num{1, 2, 3};
	vector> res = Solution().permute(num);
	for (int i = 0; i < res.size(); i++) {
		for (int j = 0; j < res[i].size(); j++)
			cout << res[i][j];
		cout << endl;
	}
	system("pause");
	return 0;
}

leetcode 78. 子集

code1

#include
#include

using namespace std;

class Solution {
private:
	void generation(int i, vector& nums, vector& item, vector>& result) {
		if (i>=nums.size()) {
			return;	
		}
		
		item.push_back(nums[i]);
		result.push_back(item);
		generation(i + 1, nums, item, result);
		item.pop_back();
		generation(i + 1, nums, item, result);	
	}
public:
	vector> subsets(vector& nums) {
		vector item;
		vector> result;
		result.push_back(item);
		generation(0, nums, item, result);
		return result;
	}
};
int main() {
	vector nums;
	nums.push_back(1);
	nums.push_back(2);
	nums.push_back(3);
	vector> result = Solution().subsets(nums);
	for (int i = 0; i < result.size(); i++) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << result[i][j] << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

code2

#include
#include

using namespace std;

class Solution {
private:
	void generation(int pos, vector& nums, vector& item, vector>& result) {
		result.push_back(item);
		for (int i = pos; i < nums.size(); i++) {
			item.push_back(nums[i]);
			generation(i + 1, nums, item, result);
			item.pop_back();
		}
	}
public:
	vector> subsets(vector& nums) {
		vector item;
		vector> result;
		generation(0, nums, item, result);
		return result;
	}
};
int main() {
	vector nums;
	nums.push_back(1);
	nums.push_back(2);
	nums.push_back(3);
	vector> result = Solution().subsets(nums);
	for (int i = 0; i < result.size(); i++) {
		for (int j = 0; j < result[i].size(); j++) {
			cout <

LeetCode 79 单词搜索

#include
#include
#include

using namespace std;

class Solution {
public:
	bool exist(vector>& board, string word) {
		if (board.empty() || board[0].empty()) return false;
		int m = board.size(), n = board[0].size();
		vector> visited(m, vector(n));
		for (int i = 0; i < m; ++i) {
			for (int j = 0; j < n; ++j) {
				if (search(board, word, 0, i, j, visited)) return true;
			}
		}
		return false;
	}
	bool search(vector>& board, string word, int idx, int i, int j, vector>& visited) {
		if (idx == word.size()) return true;
		int m = board.size(), n = board[0].size();
		if (i < 0 || j < 0 || i >= m || j >= n || visited[i][j] || board[i][j] != word[idx]) return false;
		visited[i][j] = true;
		bool res = search(board, word, idx + 1, i - 1, j, visited)
			|| search(board, word, idx + 1, i + 1, j, visited)
			|| search(board, word, idx + 1, i, j - 1, visited)
			|| search(board, word, idx + 1, i, j + 1, visited);
		visited[i][j] = false;
		return res;
	}
};
int main() {
	vector> board = 
	        {
		    {'A', 'B', 'C', 'E'},
			{'S', 'F', 'C', 'S'},
			{'A', 'D', 'E', 'E'}
	        };
	string word = "ABCCED";
	bool res = Solution().exist(board, word);
	cout << res << endl; 
	system("pause");
	return 0;
}

LeetCode 90 子集2

#include
#include
#include

using namespace std;

class Solution {
public:
	vector> subsetsWithDup(vector &S) {
		if (S.empty()) return {};
		vector> res;
		vector out;
		sort(S.begin(), S.end());
		getSubsets(S, 0, out, res);
		return res;
	}
	void getSubsets(vector &S, int pos, vector &out, vector> &res) {
		res.push_back(out);
		cout << endl;
		for (int i = pos; i < S.size(); ++i) {
			out.push_back(S[i]);
			getSubsets(S, i + 1, out, res);
			out.pop_back();
			while (i + 1 < S.size() && S[i] == S[i + 1]) 
				++i;
		}
	}
};
int main() {
	vector nums = {2,1,2,2};
	vector> result = Solution().subsetsWithDup(nums);
	for (int i = 0; i < result.size(); i++) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << result[i][j] << " ";
		}
		cout << endl;
	}
	system("pause");
	return 0;
}

LeetCode 93 复原IP地址

#include
#include
#include
#include

using namespace std;

class Solution {
public:
	vector restoreIpAddresses(string s) {
		vector res;
		restore(s, 4, "", res);
		return res;
	}
	void restore(string s, int k, string out, vector &res) {
		if (k == 0) {
			if (s.empty()) res.push_back(out);
		}
		else {
			for (int i = 1; i <= 3; ++i) {
				if (s.size() >= i && isValid(s.substr(0, i))) {
					if (k == 1) restore(s.substr(i), k - 1, out + s.substr(0, i), res);
					else restore(s.substr(i), k - 1, out + s.substr(0, i) + ".", res);
				}
			}
		}
	}
	bool isValid(string s) {
		if (s.empty() || s.size() > 3 || (s.size() > 1 && s[0] == '0')) return false;
		int res = atoi(s.c_str());
		return res <= 255 && res >= 0;
	}
};
int main() {
	string s = "25525511135";
	vector result = Solution().restoreIpAddresses(s);
	for (int i = 0; i < result.size(); i++) {
		cout << result[i] << endl;
	}
	system("pause");
	return 0;
}

LeetCode 131 分隔回文串

如果原字符串是 abcd, 那么访问顺序为: a -> b -> c -> d -> cd -> bc -> bcd-> ab -> abc -> abcd, 这是对于没有两个或两个以上子回文串的情况。那么假如原字符串是 aabc,那么访问顺序为:a -> a -> b -> c -> bc -> ab -> abc -> aa -> b -> c -> bc -> aab -> aabc。
leetcode回溯法专栏(详解)_第2张图片

#include
#include
#include

using namespace std;

class Solution {
public:
	vector> partition(string s) {
		vector> res;
		vector out;
		helper(s, 0, out, res);
		return res;
	}
	void helper(string s, int start, vector& out, vector>& res) {
		if (start == s.size()) { 
			res.push_back(out); 
			return;
		}
		for (int i = start; i < s.size(); ++i) {
			if (!isPalindrome(s, start, i)) continue;
			out.push_back(s.substr(start, i - start + 1));
			helper(s, i + 1, out, res);
			out.pop_back();
		}
	}
	bool isPalindrome(string s, int start, int end) {
		while (start < end) {
			if (s[start] != s[end]) return false;
			++start; --end;
		}
		return true;
	}
};

int main() {
	string s = "aabc";

	vector> res = Solution().partition(s);
	for (int i = 0; i < res.size(); i++) {
		for (int j = 0; j < res[i].size(); j++) {
			cout << res[i][j] << " ";
		}
	}
	system("pause");
	return 0;
}

你可能感兴趣的:(算法笔试,C++,算法与数据结构,leetcode)