【CODE】DFS && 回文字符串

目录

93. Restore IP Addresses

46. Permutations

22. Generate Parentheses

17. Letter Combinations of a Phone Number

494. Target Sum

5. Longest Palindromic Substring

647. Palindromic Substrings

516. Longest Palindromic Subsequence

131. Palindrome Partitioning

132. Palindrome Partitioning II


​​​​​​​

93. Restore IP Addresses

Medium

970435Add to ListShare

Given a string containing only digits, restore it by returning all possible valid IP address combinations.

Example:

Input: "25525511135"
Output: ["255.255.11.135", "255.255.111.35"]
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*93.Restore IP Addresses
Runtime: 4 ms, faster than 68.60% of C++ online submissions for Restore IP Addresses.
Memory Usage: 8.1 MB, less than 100.00% of C++ online submissions for Restore IP Addresses.*/
void DFS(int now,int rest, vector<string> &res, string s,string tmp) {
	if (rest == 0 && s.size() == 0) {
		tmp += to_string(now);
		res.push_back(tmp);
		return;
	}
	if (rest ==0 && now>0) {
		
		for (int i = 0; i < s.size(); i++) {
			now = now * 10 + (s[i] - '0');
		}
		if (now <= 255 ) {
			tmp += to_string(now);
			res.push_back(tmp);
		}
		return;
	}
	//从这儿分
	if (s.size()>=rest && s.size()<=rest*3) {
		string tmpp = tmp;
		tmp += to_string(now)+"." ;
		int n = stoi(s.substr(0, 1));
		if (n <= 255) {
			DFS(n, rest - 1, res, s.substr(1, s.size() - 1), tmp);
		}
		tmp = tmpp;
	}
	//加上下一位
	if (s.size() >= 1 && now!=0) {
		int nn = now * 10 + (s[0] - '0');
		if (nn <= 255 && nn>0) {
			if(s.size()-1 >= rest && s.size()-1 <= rest * 3){
				string tmpp = tmp;
				tmp += to_string(nn)+"." ;
				int n = stoi(s.substr(1, 1));
				if (n <= 255) {
					DFS(n, rest - 1, res, s.substr(2, s.size() - 1), tmp);
				}
				tmp = tmpp;
			}
		}
	}
	//加上下两位
	if (s.size() >= 2 && now!=0) {
		int nn = (now * 10 + (s[0] - '0'))*10+(s[1]-'0');
		if (nn <= 255 && nn>0) {
			if (s.size()-2 >= rest && s.size()-2 <= rest * 3) {
				string tmpp = tmp;
				tmp += to_string(nn) + ".";
				int n = stoi(s.substr(2, 1));
				if (n <= 255) {
					DFS(n, rest - 1, res, s.substr(3, s.size() - 1), tmp);
				}
				tmp = tmpp;
			}
		}
	}
	return;
}
vector<string> restoreIpAddresses(string s) {
	vector<string> res;
	if (s.size() < 4) return res;
	int now = s[0]-'0';
	int rest = 3;
	string tmp ="";
	DFS(now, rest, res, s.substr(1,-1), tmp);
	return res;
}
int main() {
	vector<string> res = restoreIpAddresses("");
	for (int i = 0; i < res.size(); i++) {
		cout << res[i] << endl;
	}
	return 0;
}

46. Permutations

Medium

308792Add to ListShare

Given a collection of distinct integers, return all possible permutations.

Example:

Input: [1,2,3]
Output:
[
  [1,2,3],
  [1,3,2],
  [2,1,3],
  [2,3,1],
  [3,1,2],
  [3,2,1]
]
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*46. Permutations
Runtime: 12 ms, faster than 70.36% of C++ online submissions for Permutations.
Memory Usage: 8.7 MB, less than 100.00% of C++ online submissions for Permutations.*/
void DFS(vector<int> &vis, vector<int> nums, vector<int> &tmp,vector<vector<int> > &res, int num) {
	if (num == nums.size()) {
		res.push_back(tmp);
		return;
	}
	for (int i = 0; i < nums.size(); i++) {
		if (vis[i] == 0) {
			tmp.push_back(nums[i]);
			vis[i] = 1;
			DFS(vis, nums, tmp, res, num + 1);
			vis[i] = 0;
			tmp.pop_back();
		}
	}
	return;
}
vector<vector<int>> permute(vector<int>& nums) {
	vector<int> vis(nums.size());
	vector<int> tmp;
	vector<vector<int> > res;
	int nmm = 0;
	DFS(vis, nums, tmp, res, 0);
	return res;
}
int main() {
	vector<int> nums = { 1,2,3 };
	vector<vector<int> > res = permute(nums);
	for (int i = 0; i < res.size(); i++) {
		for (int j = 0; j < res[0].size(); j++) {
			cout << res[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
}

22. Generate Parentheses

Medium

4141230Add to ListShare

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*22. Generate Parentheses
Runtime: 8 ms, faster than 56.24% of C++ online submissions for Generate Parentheses.
Memory Usage: 16.6 MB, less than 76.86% of C++ online submissions for Generate Parentheses.*/
void DFS(int a, int b, vector<string> &res, string tmp) {
	if (a == 0 && b == 0) {
		res.push_back(tmp);
		return;
	}
	if (a == b) {//左右括号数量相等,下一个只能是左括号
		DFS(a - 1, b, res, tmp + "(");
	}
	else if (a < b) {//左括号大于右括号个数,下一个可以是左括号也可以是右括号
		if(a>0) DFS(a - 1, b, res, tmp + "(");
		DFS(a, b - 1, res, tmp + ")");
	}
	return;
}
vector<string> generateParenthesis(int n) {
	vector<string> res;
	string tmp = "";
	DFS(n, n, res, tmp);
	return res;
}
int main() {
	vector<string> res = generateParenthesis(3);
	for (int i = 0; i < res.size(); i++) {
		cout << res[i] << endl;
	}
	return 0;
}

17. Letter Combinations of a Phone Number

Medium

3185366Add to ListShare

Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent.

A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters.

Example:

Input: "23"
Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].

Note:

Although the above answer is in lexicographical order, your answer could be in any order you want.

#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*17. Letter Combinations of a Phone Number
2:a,b,c;3:d,e,f
4:g,h,i;5:k,j,l;6:m,n,o
7:p,q,r,s;8:t,u,v;9:w,x,y,z
DFS:
Runtime: 4 ms, faster than 60.75% of C++ online submissions for Letter Combinations of a Phone Number.
Memory Usage: 9.6 MB, less than 5.71% of C++ online submissions for Letter Combinations of a Phone Number.*/
void DFS(vector<int> digits, int tar,vector<vector<string> > num, vector<string> &res, string tmp) {
	if (tar == digits.size()) {
		res.push_back(tmp);
		return;
	}
	for (int j = 0; j < num[digits[tar] - 2].size(); j++) {
		DFS(digits, tar + 1, num, res, tmp + num[digits[tar] - 2][j]);
	}
	return;
}
vector<string> letterCombinations(string digits) {
	vector<vector<string> > num = { {"a","b","c"},{"d","e","f"},
	{"g","h","i"},{"k","j","l"},{"m","n","o"},{"p","q","r","s"},{"t","u","v"},{"w","x","y","z"} };
	vector<string> res;
	if (digits.size() == 0) return res;
	string tmp = "";
	vector<int> digit;
	for (int i = 0; i < digits.size(); i++) {
		digit.push_back(digits[i] - '0');
	}
	DFS(digit, 0, num, res, tmp);
	return res;
}
int main() {
	vector<string> res = letterCombinations("23");
	for (int i = 0; i < res.size(); i++) {
		cout << res[i] << endl;
	}
	return 0;
}

494. Target Sum

Medium

197591Add to ListShare

You are given a list of non-negative integers, a1, a2, ..., an, and a target, S. Now you have 2 symbols + and -. For each integer, you should choose one from + and - as its new symbol.

Find out how many ways to assign symbols to make sum of integers equal to target S.

Example 1:

Input: nums is [1, 1, 1, 1, 1], S is 3. 
Output: 5
Explanation: 

-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3

There are 5 ways to assign symbols to make the sum of nums be target 3.

Note:

  1. The length of the given array is positive and will not exceed 20.
  2. The sum of elements in the given array will not exceed 1000.
  3. Your output answer is guaranteed to be fitted in a 32-bit integer.
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
using namespace std;
/*494. Target Sum
1.简单DFS,超时:[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1] 1*/
void DFS1(vector<int> &nums, int S, int SS, int tar,int &res) {
	if (tar == nums.size() && SS == S) {
		res++;
		return;
	}
	if (tar == nums.size()) return;
	DFS1(nums, S, SS + nums[tar], tar+1,res);
	DFS1(nums, S, SS - nums[tar], tar+1,res);
	return;
}
/*2.使用demo数组记录中间值
demo记录遍历到nums数组第几位时可能产生的结果的个数
sum记录当前离目标值还有多少
如果遍历到nums尾部(tar=nums.size()),判断sum是否为0,是的话,返回1
如果当前遍历到的位置,在demo中有过sum的产生,则直接返回demo[tar][sum]的值
否则,分别记录下一步是+ / - 时的情况个数
最后,当前tar和sum等于上述两种情况之和。
Runtime: 204 ms, faster than 46.87% of C++ online submissions for Target Sum.
Memory Usage: 56.8 MB, less than 7.69% of C++ online submissions for Target Sum.*/
int DFS2(vector<int> &nums, long sum,int tar,vector<unordered_map<int,int> > &demo){
	if (tar == nums.size()) return sum == 0;
	if (demo[tar].count(sum)) return demo[tar][sum];
	int cnt1 = DFS2(nums, sum + nums[tar], tar + 1, demo);
	int cnt2 = DFS2(nums, sum - nums[tar], tar + 1, demo);
	demo[tar][sum] = cnt1 + cnt2;
	return demo[tar][sum];
}
/*3.使用dp[i][j]记录,记录遍历到i,和为j的情况个数
Runtime: 148 ms, faster than 54.14% of C++ online submissions for Target Sum.
Memory Usage: 46.1 MB, less than 15.38% of C++ online submissions for Target Sum.*/
int findTargetSumWays1(vector<int>& nums, int S) {
	vector<unordered_map<int, int> > dp(nums.size()+1);
	dp[0][0] = 1;
	for (int i = 0; i < nums.size(); i++) {
		for (auto &a : dp[i]) {
			int sum = a.first;
			int cnt = a.second;
			dp[i + 1][sum + nums[i]] += cnt;
			dp[i + 1][sum - nums[i]] += cnt;
		}
	}
	return dp[nums.size()][S];
}
/*4.对3进行空间上的优化,只用一个HashMap,而不是用一个数组的哈希表
在遍历每个数字时,新建一个HashMap,遍历原HashMap中的项时,更新这个新的HashMap
最后把新的HashMap整个赋值给HashMap
Runtime: 148 ms, faster than 54.14% of C++ online submissions for Target Sum.
Memory Usage: 50.1 MB, less than 15.38% of C++ online submissions for Target Sum.*/
int findTargetSumWays2(vector<int>& nums, int S) {
	unordered_map<int, int> dp;
	dp[0] = 1;
	for (int i = 0; i < nums.size(); i++) {
		unordered_map<int, int> tmp;
		for (auto &a : dp) {
			int sum = a.first;
			int cnt = a.second;
			tmp[sum + nums[i]] += cnt;
			tmp[sum - nums[i]] += cnt;
		}
		dp = tmp;
	}
	return dp[S];
}
int main() {
	vector<int> nums = { 1,1,1,1,1 };
	cout << findTargetSumWays2(nums, 3);
	return 0;
} 

5. Longest Palindromic Substring

Medium

5585475Add to ListShare

Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.

Example 1:

Input: "babad"
Output: "bab"
Note: "aba" is also a valid answer.

Example 2:

Input: "cbbd"
Output: "bb"
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*5.Longest Palindromic Substring
最长回文子串,dp[i][i]=s[i]
if(s[i]==s[i-1]) dp[i-1][i]="s[i-1][i]"
if(s[i]==s[j]) dp[i][j]="s[i]"+dp[i+1][j-1]+"s[j]" maxlen;
else dp[i][j]=dp[i+1][j-1]
Runtime: 212 ms, faster than 21.29% of C++ online submissions for Longest Palindromic Substring.
Memory Usage: 185.8 MB, less than 8.96% of C++ online submissions for Longest Palindromic Substring.*/
string longestPalindrome(string s) {
	if (s.empty()) return "";
	int n = s.size();
	vector<vector<int> > dp(n, vector<int>(n));
	int left = 0, len = 1;
	for (int i = 0; i < n; i++) {
		dp[i][i] = 1;
		for (int j = 0; j < i; j++) {
			if (s[i] == s[j] && (dp[j + 1][i - 1] == 1 || i - j == 1)) dp[j][i] = 1;
			if (dp[j][i] == 1 && len < i - j + 1) {
				len = i - j + 1;
				left = j;
			}
		}
	}
	return s.substr(left, len);
}
int main() {
	string res = longestPalindrome("asdsa");
	return 0;
} 

647. Palindromic Substrings

Medium

202999Add to ListShare

Given a string, your task is to count how many palindromic substrings in this string.

The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.

Example 1:

Input: "abc"
Output: 3
Explanation: Three palindromic strings: "a", "b", "c".

Example 2:

Input: "aaa"
Output: 6
Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

Note:

  1. The input string length won't exceed 1000.
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
using namespace std;
/*647. Palindromic Substrings
Runtime: 20 ms, faster than 41.28% of C++ online submissions for Palindromic Substrings.
Memory Usage: 21.5 MB, less than 12.00% of C++ online submissions for Palindromic Substrings.*/
int countSubstrings(string s) {
	int n = s.size();
	int res = 0;
	vector<vector<int> > dp(n, vector<int>(n));
	for (int i = 0; i < n; i++) {
		dp[i][i] = 1;
		res++;
		for (int j = 0; j < i; j++) {
			if ((i - j == 1 || dp[j + 1][i - 1] == 1) && s[i] == s[j]) {
				dp[j][i] = 1;
				res++;
			}
		}
	}
	return res;
}
int main() {
	cout << countSubstrings("aaaaa");//15
	return 0;
} 

516. Longest Palindromic Subsequence

Medium

1440164Add to ListShare

Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000.

Example 1:
Input:"bbbab"

Output:4

One possible longest palindromic subsequence is "bbbb".

Example 2:
Input:"cbbd"

Output:2

One possible longest palindromic subsequence is "bb".

#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
/*516. Longest Palindromic Subsequence
最长回文子序列
Runtime: 104 ms, faster than 26.32% of C++ online submissions for Longest Palindromic Subsequence.
Memory Usage: 68.4 MB, less than 100.00% of C++ online submissions for Longest Palindromic Subsequence.*/
int longestPalindromeSubseq1(string s) {
	int n = s.size();
	if (n == 0) return 0;
	int len = 1;
	vector<vector<int> > dp(n, vector<int>(n));
	for (int i = 0; i < n; i++) {
		dp[i][i] = 1;
		for (int j = i - 1; j >= 0;j--) {
			if (s[i] == s[j] && i-j!=1) dp[j][i] = dp[j + 1][i-1] + 2;
			else if (s[i] == s[j] && i - j == 1) dp[j][i] = 2;
			else dp[j][i] = max(dp[j+1][i],dp[j][i-1]);
			if (dp[j][i] > len) len = dp[j][i];
		}
	}
	return len;
}
/*使用demo数组存储:
Runtime: 68 ms, faster than 68.17% of C++ online submissions for Longest Palindromic Subsequence.
Memory Usage: 69.1 MB, less than 100.00% of C++ online submissions for Longest Palindromic Subsequence.*/
int DFS(string &s, int i, int j, vector<vector<int> > &demo) {
	if (demo[i][j] != -1) return demo[i][j];
	if (i > j) return 0;
	if (i == j) return 1;
	if (s[i] == s[j]) demo[i][j] = DFS(s, i + 1, j - 1, demo)+2;
	else demo[i][j] = max(DFS(s, i + 1, j, demo), DFS(s, i, j - 1, demo));
	return demo[i][j];
}
int longestPalindromeSubseq(string s) {
	vector<vector<int> > demo(s.size(), vector<int>(s.size(),-1));
	return DFS(s, 0, s.size() - 1, demo);
}
int main() {
	cout << longestPalindromeSubseq("mvkxittxjnlltmoo");
	return 0;
} 

131. Palindrome Partitioning

Medium

141455Add to ListShare

Given a string s, partition s such that every substring of the partition is a palindrome.

Return all possible palindrome partitioning of s.

Example:

Input: "aab"
Output:
[
  ["aa","b"],
  ["a","a","b"]
]
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*131. Palindrome Partitioning
输入字符串,分割该串,使得返回的子串的所有子串都是回文的。
求一个字符串的所有子串:
1.以下判断回文的方法占用资源大
Runtime: 68 ms, faster than 23.05% of C++ online submissions for Palindrome Partitioning.
Memory Usage: 33.4 MB, less than 75.00% of C++ online submissions for Palindrome Partitioning.
*/
bool isPalindrome(string s) {
	string t = s;
	reverse(t.begin(), t.end());
	if (s == t) return true;
	else return false;
}
void DFS1(string s,int start, vector<string> &tmp, vector<vector<string> > &res,unordered_map<string,int> &mp) {
	if (start==s.size()) {
		res.push_back(tmp);
		return;
	}
	for (int j = 1; j <= s.size() - start;j++) {
		string ss = s.substr(start,j);
		if (mp.find(ss) == mp.end()) {
			if (isPalindrome(ss)) {
				mp[ss] = 1;
				tmp.push_back(ss);
				DFS1(s,start+j, tmp, res,mp);
				tmp.pop_back();
			}
			else mp[ss] = 0;
		}
		else if (mp[ss] == 1) {
			tmp.push_back(ss);
			DFS1(s, start + j, tmp, res, mp);
			tmp.pop_back();
		}
	}
	return;
}
vector<vector<string>> partition1(string s) {
	vector<string> tmp;
	vector<vector<string> > res;
	unordered_map<string, int> mp;
	DFS1(s, 0,tmp, res,mp);
	return res;
}
/*2.使用一个二位数组,记录从i到j是否是回文
效果并不好,demo使用bool类型会更好一些*/
void DFS(string s, int start, vector<string> &out, vector<vector<string> > &res, vector<vector<int> > demo) {
	if (start == s.size()) {
		res.push_back(out);
		return;
	}
	for (int i = start; i < s.size(); i++) {
		if (demo[start][i] == 1) {
			out.push_back(s.substr(start,i-start+1));
			DFS(s, i+1, out, res, demo);
			out.pop_back();
		}
		else continue;
	}
	return;
}
vector<vector<string>> partition(string s) {
	vector<string> out;
	vector<vector<string> > res;
	vector<vector<int> > dp(s.size(), vector<int>(s.size()));
	for (int i = 0; i < s.size(); i++) {
		for (int j = 0;j<=i;j++){
			if (s[i] == s[j] && (i - j <= 2 || dp[j + 1][i - 1] == 1)) dp[j][i] = 1;
		}
	}
	DFS(s, 0, out, res, dp);
	return res;
}
int main() {
	string s = "abc";
	vector<vector<string> > res = partition(s);
	for (int i = 0; i < res.size(); i++) {
		for (int j = 0; j < res[i].size(); j++) {
			cout << res[i][j] << " ";
		}
		cout << endl;
	}
	return 0;
} 

132. Palindrome Partitioning II

Hard

85529Add to ListShare

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

Example:

Input: "aab"
Output: 1
Explanation: The palindrome partitioning ["aa","b"] could be produced using 1 cut.
#include"pch.h"
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<unordered_map>
using namespace std;
/*132. Palindrome Partitioning II
1.分割string,使其每个分割下来的子串都是回文,返回最少需要的分割次数
如果使用DFS分割,求最小分割次数,就是最少子串个数
超时了*/
void DFS1(string s, int start, vector<string> &tmp, int &minn,vector<vector<bool> > dp) {
	if (start == s.size()) {
		minn = tmp.size() < minn ? tmp.size() : minn;
		return;
	}
	for (int i = s.size() - 1; i >= start;i--) {
		if (dp[start][i]) {
			tmp.push_back(s.substr(start, i - start + 1));
			DFS1(s, i + 1, tmp, minn, dp);
			tmp.pop_back();
		}
		else continue;
	}
	return;
}
int minCut1(string s) {
	vector<string> tmp;
	int minn = INT_MAX;
	vector<vector<bool> > dp(s.size(), vector<bool>(s.size()));
	for (int i = 0; i < s.size(); i++) {
		for (int j = 0; j <= i; j++) {
			if (s[i] == s[j] && (i - j <= 2 || dp[j + 1][i - 1])) dp[j][i] = true;
		}
	}
	DFS1(s, 0, tmp, minn, dp);
	return minn-1;
}
/*2.dp[i]记录0->i的最小分割次数
将0->i分成0-j-1和j->i,已经得出dp[j-1],下面就是判断j->i是否是回文串
如果是,则dp[i]=dp[j-1]+1
Runtime: 24 ms, faster than 65.73% of C++ online submissions for Palindrome Partitioning II.
Memory Usage: 8.6 MB, less than 93.33% of C++ online submissions for Palindrome Partitioning II.*/
int minCut(string s) {
	int n = s.size();
	vector<vector<bool> > demo(n, vector<bool>(n));
	vector<int> dp(n);
	for (int i = 0; i < n; i++) {
		dp[i] = i;//长度为0->i,即i+1的字串,最多割i道
		for (int j = 0; j <= i; j++) {
			if (s[i] == s[j] && (i - j <= 2 || demo[j + 1][i - 1])) {
				demo[j][i] = true;
				dp[i] = (j == 0) ? 0 : min(dp[j - 1] + 1, dp[i]);
			}
		}
	}
	return dp[n - 1];
}
int main() {
	cout << minCut("ababababababababababababcbabababababababababababa");
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值