wy的leetcode刷题记录_Day8
面试题 01.02. 判定是否互为字符重排
今天的每日一题是:面试题 01.02. 判定是否互为字符重排
题目介绍
给定两个字符串 s1 和 s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。
示例 1:
输入: s1 = “abc”, s2 = “bca”
输出: true
示例 2:
输入: s1 = “abc”, s2 = “bad”
输出: false
思路
方法一:暴力解决。
方法二:先对俩个字符串进行排序,然后比较。
方法三:因为已知是字符集,所以只需要维护一个128元素的hashtable
代码
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
if (s1.length() != s2.length()) {
return false;
}
sort(s1.begin(), s1.end());
sort(s2.begin(), s2.end());
return s1 == s2;
}
};
class Solution {
public:
bool CheckPermutation(string s1, string s2) {
int s1_size=s1.size();
int s2_size=s2.size();
if(s1_size!=s2_size)
return false;
vector<int> hash(128,0);
for(int i=0;i<s1_size;i++)
{
hash[s1[i]]++;
}
for(int i=0;i<s2_size;i++)
{
hash[s2[i]]--;
if(hash[s2[i]]<0)
return false;
}
return true;
}
};
收获
1.巩固hash知识
474. 一和零
题目介绍
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
示例 1:
输入:strs = [“10”, “0001”, “111001”, “1”, “0”], m = 5, n = 3
输出:4
解释:最多有 5 个 0 和 3 个 1 的最大子集是 {“10”,“0001”,“1”,“0”} ,因此答案是 4 。 其他满足题意但较小的子集包括{“0001”,“1”} 和 {“10”,“1”,“0”} 。{“111001”} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3。
示例 2:
输入:strs = [“10”, “0”, “1”], m = 1, n = 1
输出:2
解释:最大的子集是 {“0”, “1”},所以答案是 2 。
思路
背包!
1.确定dp数组的含义:dp[i][j]:最多有i个0和j个1的strs的最⼤⼦集的⼤⼩为dp[i][j]。
2.确定dp数组的递推公式:dp[i][j] 可以由前⼀个strs⾥的字符串推导出来,strs⾥的字符串有zeroNum个0,oneNum个1。dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
3.初始化:初始所有dp为0
4.自己举例推导一遍
代码
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(string str:strs)
{
int oneNum=0,zeroNum=0;
for(char c:str)
{
if(c=='0')
zeroNum++;
else if(c=='1')
oneNum++;
}
for (int i = m; i >= zeroNum; i--) // 遍历背包容量且从后向前遍历!
{
for (int j = n; j >= oneNum; j--)
{
dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
}
}
}
return dp[m][n];
}
};
收获
巩固了背包问题的四步骤