leetcode回溯法专栏(详解)

预备知识(递归)

#include<iostream>
#include<vector>

using namespace std;

class Solution {
public:
	void generation(int i, vector<int>& nums, vector<int>& item, vector<vector<int>>& result) {
		if (i>=nums.size()) {
			return;	
		}
		item.push_back(nums[i]);
		result.push_back(item);
		generation(i+1, nums, item, result);
	}
};
int main() {
	vector<int> nums;
	nums.push_back(1);
	nums.push_back(2);
	nums.push_back(3);
	vector<int> item;
	vector<vector<int>> 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<iostream>
#include<vector>
#include<string>

using namespace std;

class Solution {
public:
	vector<string> letterCombinations(string digits) {
		if (digits.empty()) return {};
		vector<string> res;
		vector<string> dict{ " ", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };
		letterCombinationsDFS(digits, dict, 0, "", res);
		return res;
	}
	void letterCombinationsDFS(string& digits, vector<string>& dict, int level, string out, vector<string>& 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<string> res = Solution().letterCombinations("234");
	for (int i = 0; i < res.size(); i++)
		cout << res[i] << endl;
	system("pause");
	return 0;
}

code2

#include<iostream>
#include<vector>
#include<assert.h>
#include<string>

using namespace std;

class Solution {
private:
	vector<string> 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<string> letterCombinations(string digits) {
		res.clear();
		if (digits == "") return res;
		findCombinations(digits,0,"");
		return res;
	}
};
int main() {
	string digits = "23";
	vector<string> res = Solution().letterCombinations(digits);
	for (int i = 0; i < res.size(); ++i) {
		cout << res[i] << endl;
	}
	system("pause");
	return 0;
}

LeetCode 39 组合总和

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
		vector<vector<int>> res;
		vector<int> out;
		combinationSumDFS(candidates, target, 0, out, res);
		return res;
	}
	void combinationSumDFS(vector<int>& candidates, int target, int start, vector<int>& out, vector<vector<int>>& 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<int> candidates = {2,3,6,7};
	int target = 7;
	vector<vector<int>> 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<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	vector<vector<int> > combinationSum2(vector<int> &num, int target) {
		vector<vector<int> > res;
		vector<int> out;
		sort(num.begin(), num.end());
		combinationSum2DFS(num, target, 0, out, res);
		return res;
	}
	void combinationSum2DFS(vector<int> &num, int target, int start, vector<int> &out, vector<vector<int> > &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<int> candidates = {2,2,2,2,1,7};
	int target = 8;
	vector<vector<int>> 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 全排列

图解

在这里插入图片描述

code1

#include<iostream>
#include<vector>

using namespace std;

class Solution {
public:
	vector<vector<int>> permute(vector<int>& num) {
		vector<vector<int>> res;
		permuteDFS(num, 0, res);
		return res;
	}
	void permuteDFS(vector<int>& num, int start, vector<vector<int>>& 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<int> num{1,2,3};
	vector<vector<int>> 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 <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Solution {
private:
	vector<vector<int>> res;
	vector<bool> used;
	void generatePermutation(const vector<int>& nums, int index, vector<int>& 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<vector<int>> permute(vector<int>& nums) {
		res.clear();
		if (nums.size() == 0)
			return res;
		used = vector<bool>(nums.size(), false);
		vector<int> p;
		generatePermutation(nums, 0, p);
		return res;
	}
};
int main() {
	vector<int> num{1, 2, 3};
	vector<vector<int>> 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<iostream>
#include<vector>

using namespace std;

class Solution {
private:
	void generation(int i, vector<int>& nums, vector<int>& item, vector<vector<int>>& 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<vector<int>> subsets(vector<int>& nums) {
		vector<int> item;
		vector<vector<int>> result;
		result.push_back(item);
		generation(0, nums, item, result);
		return result;
	}
};
int main() {
	vector<int> nums;
	nums.push_back(1);
	nums.push_back(2);
	nums.push_back(3);
	vector<vector<int>> 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<iostream>
#include<vector>

using namespace std;

class Solution {
private:
	void generation(int pos, vector<int>& nums, vector<int>& item, vector<vector<int>>& 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<vector<int>> subsets(vector<int>& nums) {
		vector<int> item;
		vector<vector<int>> result;
		generation(0, nums, item, result);
		return result;
	}
};
int main() {
	vector<int> nums;
	nums.push_back(1);
	nums.push_back(2);
	nums.push_back(3);
	vector<vector<int>> 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;
}

LeetCode 79 单词搜索

#include<iostream>
#include<vector>
#include<string>

using namespace std;

class Solution {
public:
	bool exist(vector<vector<char>>& board, string word) {
		if (board.empty() || board[0].empty()) return false;
		int m = board.size(), n = board[0].size();
		vector<vector<bool>> visited(m, vector<bool>(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<vector<char>>& board, string word, int idx, int i, int j, vector<vector<bool>>& 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<vector<char>> 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<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class Solution {
public:
	vector<vector<int>> subsetsWithDup(vector<int> &S) {
		if (S.empty()) return {};
		vector<vector<int>> res;
		vector<int> out;
		sort(S.begin(), S.end());
		getSubsets(S, 0, out, res);
		return res;
	}
	void getSubsets(vector<int> &S, int pos, vector<int> &out, vector<vector<int>> &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<int> nums = {2,1,2,2};
	vector<vector<int>> 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<iostream>
#include<vector>
#include<algorithm>
#include<string>

using namespace std;

class Solution {
public:
	vector<string> restoreIpAddresses(string s) {
		vector<string> res;
		restore(s, 4, "", res);
		return res;
	}
	void restore(string s, int k, string out, vector<string> &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<string> 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。
在这里插入图片描述

#include<iostream>
#include<string>
#include<vector>

using namespace std;

class Solution {
public:
	vector<vector<string>> partition(string s) {
		vector<vector<string>> res;
		vector<string> out;
		helper(s, 0, out, res);
		return res;
	}
	void helper(string s, int start, vector<string>& out, vector<vector<string>>& 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<vector<string>> 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;
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知行SUN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值