从今天开始,下定决心正式把语言转为C++,之后也会用C++重新把前几天的题解再写一遍。加油
454.四数相加II
建议:本题是 使用map 巧妙解决的问题,好好体会一下 哈希法 如何提高程序执行效率,降低时间复杂度,当然使用哈希法 会提高空间复杂度,但一般来说我们都是舍空间 换时间, 工业开发也是这样。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0454.%E5%9B%9B%E6%95%B0%E7%9B%B8%E5%8A%A0II.html
Tips:这里使用的是unordered_map
,同时需要注意哈希表判断有无某一个元素的方式umap.find(a)!=umap.end()
我的题解:
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
unordered_map<int, int> umap;
for(int i : nums1){
for(int j : nums2){
umap[i+j]++;
}
}
int result = 0;
for(int i : nums3){
for(int j : nums4){
// 哈希表判断有无某一个元素的方式
if(umap.find(-(i+j))!=umap.end()){
result+=umap[i+j];
}
}
}
return result;
}
};
383. 赎金信
建议:本题 和 242.有效的字母异位词 是一个思路 ,算是拓展题
题目链接/文章讲解:https://programmercarl.com/0383.%E8%B5%8E%E9%87%91%E4%BF%A1.html
Tips:这个题还是用数组作为哈希表即可
我的题解:
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
// 将数组初始化为0
int history[26] = {0};
for(int i=0;i<magazine.size();i++){
history[magazine[i] - 'a']++;
}
for(int i=0;i<ransomNote.size();i++){
if(history[ransomNote[i] - 'a'] <= 0){
return false;
}
else{
history[ransomNote[i] - 'a']--;
}
}
return true;
}
};
15. 三数之和
建议:本题虽然和 两数之和 很像,也能用哈希法,但用哈希法会很麻烦,双指针法才是正解,可以先看视频理解一下 双指针法的思路,文章中讲解的,没问题 哈希法很麻烦。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0015.%E4%B8%89%E6%95%B0%E4%B9%8B%E5%92%8C.html
Tips:这道题虽然放在哈希表专题里面,但是用哈希表来做会非常复杂,主要是去重操作太难写了,说实话看代码看了很久也没太看懂去重的思路是什么,所以应该直接采用双指针法写出题解。
我的题解:
class Solution {
public:
vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i = 0;i<nums.size();i++){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
int left = i+1;
int right = nums.size() -1;
while(left<right){
if(nums[i] + nums[left] + nums[right] == 0){
result.push_back(vector<int>{nums[i], nums[left], nums[right]});
while(left < right && nums[right] == nums[right-1]){
right--;
}
while(left < right && nums[left] == nums[left + 1]){
left++;
}
right--;
left++;
}
else if(nums[i] + nums[left] + nums[right] < 0){
left++;
}
else{
right--;
}
}
}
return result;
}
};
18. 四数之和
建议: 要比较一下,本题和 454.四数相加II 的区别,为什么 454.四数相加II 会简单很多,这个想明白了,对本题理解就深刻了。 本题 思路整体和 三数之和一样的,都是双指针,但写的时候 有很多小细节,需要注意,建议先看视频。
题目链接/文章讲解/视频讲解:https://programmercarl.com/0018.%E5%9B%9B%E6%95%B0%E4%B9%8B%E5%92%8C.html
Tips:逻辑上其实就是比三数之和多了一层for循环,时间复杂度也高了一个数量级,但是思想是一样的,仍然需要注意去重的操作。
我的题解:
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> result;
sort(nums.begin(),nums.end());
for(int i = 0; i < nums.size();i++){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
for(int j = i + 1; j < nums.size(); j++){
if(j > i + 1 && nums[j] == nums[j-1]){
continue;
}
int sum = nums[i] + nums[j];
int left = j+1;
int right = nums.size() -1;
while(left< right){
// nums[k] + nums[i] + nums[left] + nums[right] > target 会溢出
if((long)sum + nums[left] + nums[right] == target){
result.push_back(vector<int>{nums[i],nums[j],nums[left],nums[right]});
while(left<right && nums[left] == nums[left+1]){
left++;
}
while(left<right && nums[right] == nums[right-1]){
right--;
}
left++;
right--;
}
else if((long)sum + nums[left] + nums[right] < target){
left++;
}
else{
right--;
}
}
}
}
return result;
}
};
标签:vector,四数,15,nums,int,三数,right,哈希,left From: https://www.cnblogs.com/GavinGYM/p/17023596.html