纪念一下leetcode刷了50题呜呜,最近总算把数据结构看完了
题目描述
找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
我的题解:
手写快排超时,然后qsort得库函数通过,感觉是哪里逻辑错误了,但是后面发现哈希好像更快就改哈希了
// void quicksort(int *nums,int left,int right){
// if(right<left){
// return;
// }
// int right0=right;
// int left0=left;
// int basenumber=nums[left];
// while(right!=left){
// while(left!=right){
// while(nums[right]>=basenumber&&right>left){
// right--;
// }
// while(nums[left]<=basenumber&&right>left){
// left++;
// }
// int temp=nums[left];
// nums[left]=nums[right];
// nums[right]=temp;
// }
// }
// int temp=nums[right];
// nums[right]=nums[left0];
// nums[left0]=temp;
// quicksort(nums,0,left-1);
// quicksort(nums,left=1,right0);
// }超时了所以用qsort
// int cmp(const void*p1,const void*p2){
// return (*(int*)p1)-(*(int*)p2);
// }//以上都是快排
int findRepeatNumber(int* nums, int numsSize){
// qsort(nums,numsSize,sizeof(int),cmp);
// for(int i=0;i<numsSize-1;++i){
// if(nums[i]==nums[i+1]){
// return nums[i];
// }
// }
// return nums;快排成功用的是库函数
//哈希表
if(nums==NULL||!numsSize)
return 0;
//动态申请空间
int *bitmap=(int*)malloc(sizeof(int)*numsSize);
for(int i=0;i<numsSize;++i){
if(bitmap[nums[i]]!=1){
bitmap[nums[i]]=0;//说明当前无元素
}
++bitmap[nums[i]];//说明放入了一个
if(bitmap[nums[i]]>1){
//说明之前已经在中间放了一个,后面在执行一个所以才会大于1
return nums[i];
}
}
return -1;//说明没有
}
我的思路:
//手动实现了一下快排发现超时了。。然后调用api的qsort过啦,第二个方法就是哈希,效率真的极高,先排序再找的方法属于是南辕北辙了有点
哈希是真快
2022/5/6(数组训练)
题目描述:
我的题解:
int maximumDifference(int* nums, int numsSize){
int max=0;
int def=0;
int min=INT_MAX;
for(int i=0;i<numsSize;++i){
//记录最小值
if(nums[i]<min){
min=nums[i];
}
def=nums[i]-min;
if(def>max){
max=def;
}
}
return max>0?max:-1;
}
我的思路:
循环遍历找到最小值,同时要保证j要在i前也就是说遍历的同时保持前面减后面找出最大值即可
题目描述
给你一个长度为 n 的整数数组 nums ,请你返回 nums 中最 接近 0 的数字。如果有多个答案,请你返回它们中的 最大值 。
我的题解:
int findClosestNumber(int* nums, int numsSize){
int min=INT_MAX;
int max=INT_MAX;
for(int i=0;i<numsSize;++i){
int temp=abs(nums[i]);
if(temp<max){
min=nums[i];
max=temp;
}else if(temp==max){
if(nums[i]>min){
min=nums[i];
}
}
}
return min;
}
我的思路:
首先准备两个变量,一个负责保存每次遍历绝对值的值,然后和前几次最小值做个对比如果不同保留小的,如果相同则保留相对来说大的
题目描述:
给你一个数组 prices ,其中 prices[i] 是商店里第 i 件商品的价格。
商店里正在进行促销活动,如果你要买第 i 件商品,那么你可以得到与 prices[j] 相等的折扣,其中 j 是满足 j > i 且 prices[j] <= prices[i] 的 最小下标 ,如果没有满足条件的 j ,你将没有任何折扣。
请你返回一个数组,数组中第 i 个元素是折扣后你购买商品 i 最终需要支付的价格。
我的题解:
利用单调栈,判处单调递增的序列(单调但并非严格单调)
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* finalPrices(int* prices, int pricesSize, int* returnSize){
//单调栈解法
int len=pricesSize;
//创建栈
int Stack[len];
//分配储存后面减完后的数组
int*res=(int*)malloc(sizeof(int)*len);
int top=-1;
Stack[++top]=0;
for(int i=1;i<len;++i){
while(top>=0&&prices[i]<=prices[Stack[top]]){
//下一个比顶部元素小,根据题意出栈相减放入数组获得新的数组
res[Stack[top]]=prices[Stack[top]]-prices[i];
--top;
}
Stack[++top]=i;//记录当前下标值
}
while(top>=0){
//把剩余未变化直接放入即可
res[Stack[top]]=prices[Stack[top]];
top--;
}
*returnSize=len;
return res;
}
我的思路:
其实就是个单调递增的单调栈的一种变形,既然是要找出比它小的数,那么先把第一个数放入尝试看看是否满足后面有比它小的,有的话则输出相减获得折扣后的值放入其中,然后依次用这种方式进行遍历,最后剩余的未被折扣的直接放入数组原来的位置中即可
题目描述:
给你一个二维整数数组 nums ,其中 nums[i] 是由 不同 正整数组成的一个非空数组,
按 升序排列 返回一个数组,数组中的每个元素在 nums 所有数组 中都出现过。
我的题解:
很经典得哈希表的题目
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* intersection(int** nums, int numsSize, int* numsColSize, int* returnSize){
//用哈希表进行映射
int HashTable[1001]={0};
int index=0;
//动态分配数组储存值
int* res=(int*)malloc(sizeof(int)*1001);
//以数组含有值得大小进行映射
for(int i=0;i<numsSize;++i){
for(int j=0;j<numsColSize[i];++j)
{
HashTable[nums[i][j]]++;
}
}
for(int i=0;i<1001;++i){
if(HashTable[i]==numsSize){
res[index++]=i;
}
}
*returnSize=index;
return res;
}
我的思路:
首先是有每个一维数组中都会出现重复值所以可以用哈希表去映射其中的关系,
用哈希表得下标表示出现的次数,
其次就是他得值大小由于是要到1000,
所以要考虑到这点动态分配到1001以免空指针访问异常,用大小关系反映映射关系还可以顺便输出得是递增得效果