目录
454.四数相加II
题目链接:力扣
题目描述:给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
示例:
输入:nums1 = [1,2], nums2 = [-2,-1], nums3 = [-1,2], nums4 = [0,2]
输出:2
解释:
两个元组如下:
1. (0, 0, 0, 1) -> nums1[0] + nums2[0] + nums3[0] + nums4[1] = 1 + (-2) + (-1) + 2 = 0
2. (1, 1, 0, 0) -> nums1[1] + nums2[1] + nums3[0] + nums4[0] = 2 + (-1) + (-1) + 0 = 0
类似于1.两数之和。用unordered_map来解决
元素值作为key,出现次数作为value。value的值可以通过map[num]来获取。
class Solution {
public:
int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
int count=0;
std::unordered_map<int,int> map;
for(int i=0;i<nums1.size();i++){
for(int j=0;j<nums2.size();j++){
int num=nums1[i]+nums2[j];
map[num]++;
}
}
for(int i=0;i<nums3.size();i++){
for(int j=0;j<nums4.size();j++){
int num=-(nums3[i]+nums4[j]);
if(map.find(num)!=map.end()){
count+=map[num];
}
}
}
return count;
}
};
383.赎金信(难度:简单√)
题目链接:力扣
题目描述:
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。
1.C 数组实现
bool canConstruct(char * ransomNote, char * magazine){
int box[26]={0};
//将后面字符串中出现的字符计数
for(int i=0;i<strlen(magazine);i++){
box[magazine[i]-'a']++;
}
for(int i=0;i<strlen(ransomNote);i++){
if(--box[ransomNote[i]-'a']<0){
return false;
}
}
return true;
}
2. C++ multiset
由于multiset允许数值重复,用以记录magazine字符串中的字符。
遍历ransomNote字符串,有字符不在muti_set中的话返回false。
要注意:
- C++中返回字符串大小函数:num.size();C中返回字符串大小函数:strlen(num)
- 在multiset中,语句set.erase(num)会删除所有key=num的元素。只删除一个可以先定义auto it=set.find(num);set.erase(it);从而只删除其中一个。
class Solution {
public:
bool canConstruct(string ransomNote, string magazine) {
std::multiset<char> set;
//将magazine中字符插入set
for(int i=0;i<magazine.size();i++){
set.insert(magazine[i]);
}
for(int i=0;i<ransomNote.size();i++){
//判断当前字符在set中?
auto it=set.find(ransomNote[i]);
if(it!=set.end()){
//由于每个字符只能用一次,因此在就删除
set.erase(it);
}else{
//不在false
return false;
}
}
return true;
}
};
15. 三数之和(看完讲解也不会)
题目链接:力扣
题目描述:
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
解释:
nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0 。
nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0 。
nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0 。
不同的三元组是 [-1,0,1] 和 [-1,-1,2] 。
注意,输出的顺序和三元组的顺序并不重要。
讲解:梦破碎的地方!| LeetCode:15.三数之和_哔哩哔哩_bilibili
整体的思路和去重都得好好想!多看几遍讲解
不能排序之后直接将数组去重,会丢解!!!
整体思路:先将数组排序。一层循环固定选择的第一个数,采用双指针left、right确定后两个数。考虑去重。
int cmp(const void* e1,const void* e2){
return *(int*)e1-*(int*)e2;
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){
int ** ret=(int **)malloc(sizeof(int*)*numsSize);
//排序
qsort(nums,numsSize,sizeof(int),cmp);
//去重返回去重后数组大小
*returnSize=0;
int sign=removeDuplicates(nums,numsSize);
if(sign<3) return ret;
for(int i=0;i<sign-2;i++){
if(nums[i]>0) break;
int left=i+1;
int right=sign-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(sum==0){
int* arr=(int*)malloc(sizeof(int)*3);
arr[0]=nums[i];
arr[1]=nums[left];
arr[2]=nums[right];
ret[(*returnSize)++]=arr;
}
if(sum>0) right--;
if(sum<0) left++;
left++;right--;
}
}
*returnColumnSizes=(int*)malloc(sizeof(int)*(*returnSize));
for(int i=0;i<(*returnSize);i++){
(*returnColumnSizes)[i]=3;
}
return ret;
}
18. 四数之和(不会,还没完成)
题目链接:力扣
讲解:梦破碎的地方!| LeetCode:15.三数之和_哔哩哔哩_bilibili
类似于15.三数之和
代码随想录没有C代码,之后学会再补充!