赞
踩
遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法
leetcode链接
代码随想录链接
一刷状态:通过
思路简单,使用unordered_map实现,统计前两个数相加的所有情况,构建<nums1[i]+nums2[j], nums>的键值对,再遍历nums3和nums4,判断map中是否存在0-nums3[i]-nums4[j]的值,找到所有满足条件的数值对。
class Solution { public: int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) { unordered_map<int, int> map; int result = 0; for(int i = 0; i<nums1.size(); i++) { for(int j = 0; j<nums2.size(); j++) { map[nums1[i]+nums2[j]]++; } } for(int i = 0; i<nums3.size(); i++) { for(int j = 0; j<nums4.size(); j++) { auto iter = map.find(0-nums3[i]-nums4[j]); if(iter!=map.end()) { result += iter->second; } } } return result; } };
leetcode链接
代码随想录链接
一刷状态:通过
思路简单,使用unordered_map,统计magazine的字母数量,再遍历ransomNote,对相应的字母减1,若出现字母数量小于0,则说明该字母未在magazine中出现,根据题目要求,返回false。
class Solution { public: bool canConstruct(string ransomNote, string magazine) { unordered_map<int, int> map; for(auto mag:magazine) { map[mag]++; } for(auto ran:ransomNote) { map[ran]--; if(map[ran]<0) return false; } return true; } };
leetcode链接
代码随想录链接
一刷状态:未通过(思路不清晰)
假设三数之和的三数分别为:a、b、c 。则遍历a,然后使用双指针的方法遍历b和c。使用双指针的方法的前提是对数组进行排序,再使用类似二分法的方法,遍历b和c,从而降低时间复杂度。
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(nums[i]>0) break; // 跳过重复的数 if(i>0&&nums[i-1]==nums[i]) continue; // 双指针法,找到相加为0-nums[i]的两个数 int left = i+1; int right = nums.size()-1; while(left < right) { if(nums[left]+nums[right]>0-nums[i]) right--; else if(nums[left]+nums[right]<0-nums[i]) left++; else { result.push_back({nums[i],nums[left],nums[right]}); while(left < right && nums[left]==nums[left+1]) left++; while(left < right && nums[right]==nums[right-1]) right--; left++; right--; } } } return result; } };
leetcode链接
代码随想录链接
一刷状态:通过(效率不高)
在三数之和的基础上增加一个循环
思考这个剪枝条件
if((long)nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) break;
if((long)nums[i]+nums[n-1]+nums[n-2]+nums[n-3]<target) continue;
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(nums[i]>target && target>=0) break; if(i>0&&nums[i]==nums[i-1]) continue; for(int j=i+1; j<nums.size();j++) { if(nums[i]+nums[j]>target && target>=0) break; if(j>i+1&&nums[j]==nums[j-1]) continue; int left = j+1; int right = nums.size()-1; while(left<right) { if((long)nums[i]+nums[j]+nums[left]+nums[right]>target) right--; else if((long)nums[i]+nums[j]+nums[left]+nums[right]<target) left++; else { result.push_back({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--; } } } } return result; } };
高效率写法
class Solution { public: vector<vector<int>> fourSum(vector<int>& nums, int target) { vector<vector<int>> ans; int n = nums.size(); if (n<4) return ans; sort(nums.begin(), nums.end()); for (int i=0; i<n-3; i++) { // if(nums[i]>target) return ans; if(i>0 && nums[i]==nums[i-1]) {continue;} if((long)nums[i]+nums[i+1]+nums[i+2]+nums[i+3]>target) {break;} if((long)nums[i]+nums[n-1]+nums[n-2]+nums[n-3]<target) {continue;} for(int j=i+1; j<n-2; j++) { if(j>i+1 && nums[j]==nums[j-1]) continue; if((long)nums[i]+nums[j]+nums[j+1]+nums[i+2]>target) {break;} if((long)nums[i]+nums[j]+nums[n-1]+nums[n-2]<target) {continue;} int L=j+1, R=n-1; while(L<R) { long su=(long)nums[i]+nums[j]+nums[L]+nums[R]; if(su==target) { ans.push_back(vector<int>{nums[i], nums[j],nums[L],nums[R]}); while(L<R && nums[L]==nums[L+1]) { L++; } while(L<R && nums[R]==nums[R-1]) { R--; } L++; R--; } else if(su>target) { R--; } else { L++; } } } } return ans; } };
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。