350.两个数的交集Ⅱ
给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可以不考虑输出结果的顺序。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2,2]
示例 2:输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[4,9]
提示:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小,哪种方法更优?
如果 nums2 的元素存储在磁盘上,内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
idea:
将两个数组排序后,得到后续数组,只要相同就可以加入到输出数组。
将两个数组排序后,如果数组A的值大于B,则指向B的指针向前移动,反之同理。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp(const void* _a, const void* _b){
return *(int*)_a-*(int*)_b;
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int *ret,count=0;
ret=malloc(sizeof(int)*(nums1Size+nums2Size));
qsort(nums1,nums1Size,sizeof(int),cmp);
qsort(nums2,nums2Size,sizeof(int),cmp);
int i=0,j=0,k=0;
while(i<nums1Size && j<nums2Size){
if(nums1[i]<nums2[j]){
i++;
}else if(nums1[i]>nums2[j]){
j++;
}else{
count++;
ret[k++]=nums1[i];
i++;
j++;
}
}
*returnSize=count;
return ret;
}
终于自己又AC一道简单题,在LC做题时发现,如果返回值为int*,不能返回数组的头部变量。
题解:
1、哈希表
2、排序+双指针
代码实现的细节学习:
1、题解没有C的实现,自己实现了一下,有报错,没有debug,后面有时间再回来改吧。。
struct hashTable{
int key;
int val;
UT_hash_handle hh;
};
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
//传参比较大小的小trick
if(nums2Size>nums1Size) return intersect(nums2,nums2Size,nums1,nums1Size,returnSize);
struct hashTable* map;
int count=0;
int* ret = malloc(sizeof(int)*nums1Size);
for(int i=0;i<nums1Size;i++){
struct hashTable* tmp;
int key = nums1[i];
HASH_FIND_INT(map,&key,tmp);
if(!tmp){
tmp=malloc(sizeof(struct hashTable));
tmp->key=nums1[i];
tmp->val=1;
HASH_ADD_INT(map,key,tmp);
}else{
tmp->val++;
}
}
for(int i=0;i<nums2Size;i++){
struct hashTable* tmp;
int key = nums2[i];
HASH_FIND_INT(map,&key,tmp);
if(tmp){
tmp->val--;
ret[count++]=tmp->key;
}
}
*returnSize=count;
return ret;
}
2、在排序和双指针中给返回数组ret分配空间时,应该取fmin(nums1Size,nums2Size),纠正之后,内存消耗小了不少。
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int cmp(const void* _a, const void* _b){
return *(int*)_a-*(int*)_b;
}
int* intersect(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
int *ret,count=0;
ret=malloc(sizeof(int)*(fmin(nums1Size,nums2Size)));
qsort(nums1,nums1Size,sizeof(int),cmp);
qsort(nums2,nums2Size,sizeof(int),cmp);
int i=0,j=0,k=0;
while(i<nums1Size && j<nums2Size){
if(nums1[i]<nums2[j]){
i++;
}else if(nums1[i]>nums2[j]){
j++;
}else{
count++;
ret[k++]=nums1[i];
i++;
j++;
}
}
*returnSize=count;
return ret;
}
121.买卖股票的最佳时机
给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。
你只能选择 某一天 买入这只股票,并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。
返回你可以从这笔交易中获取的最大利润。如果你不能获取任何利润,返回 0 。
示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。
示例 2:输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。
提示:
1 <= prices.length <= 105
0 <= prices[i] <= 104来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
idea:
用一个变量存储数组的最小变量,用一个变量存储数组的最大利润,每循环一个值便更新这两个变量最后可以得到最大利润。
int maxProfit(int* prices, int pricesSize){
int minVal=prices[0],maxProfit=0;
for(int i=1;i<pricesSize;i++){
int profit=prices[i]-minVal;
if(profit>maxProfit) maxProfit=profit;
if(prices[i]<minVal) minVal=prices[i];
}
return maxProfit;
}
题解:
1、暴力法,直接算出每天的最大利润值
2、一次遍历法,和我的写法一样,没有C的写法,就不对比了。