今天的leetcode最后一题是动态规划,比较难,适合对DP比较熟练的童鞋去完成,讲起来也比较费劲,这里就只讲下第二道和第三道题,第一道水题略过。
题目内容:
如果可以使用以下操作从一个字符串得到另一个字符串,则认为两个字符串 接近 :
操作 1:交换任意两个 现有 字符。
例如,abcde -> aecdb
操作 2:将一个 现有 字符的每次出现转换为另一个 现有 字符,并对另一个字符执行相同的操作。
例如,aacabb -> bbcbaa(所有 a 转化为 b ,而所有的 b 转换为 a )
你可以根据需要对任意一个字符串多次使用这两种操作。
给你两个字符串,word1 和 word2 。如果 word1 和 word2 接近 ,就返回 true ;否则,返回 false 。
解题思路:
刚开始看题目差点用DP的思路去解题,仔细思考后发现这道题是有规律的。
这道题输入2个字符串a和b,看是否能从a通过操作1、2转换为b。
对于操作1,任意交换2个现有字符,不管怎样交换,字符串里面的字符不会变化,也就是说,a和b的长度肯定是一样的,并且拥有的字符集也一样。
对于操作2,可以转换任意2个类型的字符,那么这里转换后,每个字符的数量按大小排序后是不变的,只要保证2个字符串中字符数量一致,那么就可以转换。
代码如下:
class Solution {
public:
bool closeStrings(string word1, string word2) {
if(word1.length() != word2.length()){
return false;
}
std::vector<int> w1(26);
std::vector<int> w2(26);
for(auto v:word1){
w1[v-'a']++;
}
for(auto v:word2){
w2[v-'a']++;
// 相同字符
if(w1[v-'a'] == 0){
return false;
}
}
// 数量相同
std::sort(w1.begin(), w1.end());
std::sort(w2.begin(), w2.end());
for(auto i=0; i<26; i++){
if(w1[i] != w2[i]){
return false;
}
}
return true;
}
};
题目内容:
给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素,然后从 x 中减去该元素的值。请注意,需要 修改 数组以供接下来的操作使用。
如果可以将 x 恰好 减到 0 ,返回 最小操作数 ;否则,返回 -1 。
解题思路:
这个题目如果直接做,需要处理两端的数据,处理起来很难受,一开始就是这种思路的,用搜索的方法解题,这道题和leetcode经典的子数组求和很像,然而这次是反着来的。
题目意思是从左边或者右边减去一个元素,使得剪掉的总值恰好是x。
反着理解其实就是:数组nums的子数组中,和为sum(nums)-x的子数组是否存在。
于是题目变得比较简单,子数组求和就是前缀和处理。
class Solution {
public:
int minOperations(vector<int>& nums, int x) {
int left = 0;
int right = left +1;
int target = 0;
for(int i=0; i<nums.size();i++){
target += nums[i];
}
int res = -1;
target -= x;
if(target ==0){
return nums.size();
}
int temp = nums[left] + nums[right];
while(left<=right && right <nums.size()){
if(temp == target){
res = max(right-left+1, res);
}
if(temp <= target){
right ++;
temp += nums[right];
}else if(temp >target){
left ++;
temp -= nums[left-1];
}
}
if(res == -1)
return res;
return nums.size() - res;
}
};
通过上面的2题目,可以发现都是将原有的题意做了一次转换,在转换后的思路上曲线解题,这样解题思路会很简单,并且效率也高,代码可读性也会好一些。
好了,这就是这周的算法题解,小编算法水平有限,第四题看了下没做出来,题解理解起来也比较花时间,就不在这篇文章里详细说明了。下周继续~
个人公众号:ACM算法日常
专注于基础算法的研究工作,深入解析ACM算法题,五分钟阅读,轻松理解每一行源代码。内容涉及算法、C/C++、软件设计等。