作为一名学院小学渣,被dalao推荐来写leetcode,第一题就耗费了我好久时间。虽说我就是那种经典的四级词汇只记得abandon的那种,但是还是有想尽量努力长期刷下去的想法,就想尝试长期写博客,希望自己能在这里坚持下去吧。
小白看这一题第一反应就是暴力遍历,于是很快码完,然后交了这么一份代码上去:
int* twoSum(int* nums, int numsSize, int target) {
int i,j;
int *index;
index = (int *)malloc(sizeof(int) * 2);
for(i = 0;i < numsSize;i++){
for(j = i + 1;j < numsSize;j++){
if(nums[i] + nums[j] == target){
index[0] = i;
index[1] = j;
break;
}
}
}
return index;
}
这份代码提交了多次,时间一般都在150ms左右徘徊,内存在7.7MB上下变化。这里如果换成leetcode-cn,时间会变成260ms左右,很奇怪,难道leetcode-cn和leetcode本家的测试用例还有不同吗emmm。
当然这肯定不是最好的解法,一开始我考虑过库排序再遍历,但是c语言qsort会把下标打乱,一般这样就必须用结构体来储存下标了,感觉这样会不会更加麻烦,就没有去尝试
一般暴力遍历最大的问题是时间问题,所以一般优化算法都是采取空间换时间的方法。一时脑子里没想到什么比较好的方法,于是去网上看了下,发现大部分都提到用哈希表。于是自己写了份哈希表代码,一开始一直都是wrong answer,代码如下:
int* twoSum(int* nums, int numsSize, int target) {
int *index, i, *HashTable;
int min=nums[0], max, len;
index = (int *)malloc(sizeof(int)*2);
for(i = 1;i < numsSize;i++){
if(nums[i] < min) min = nums[i];
}
max = target - min;
len = max - min + 1;
HashTable = (int *) malloc(sizeof(int) * len);
for(i = 0;i < len;i++){
HashTable[i] = -1;
}
for(i = 0;i < numsSize;i++){
if(nums[i] - min< len){
HashTable[nums[i] - min] = i;
if(HashTable[max - nums[i]] != -1){
index[0] = HashTable[max - nums[i]];
index[1] = i;
break;
}
}
}
return index;
}
报错:
这里还是太天真,导致他读到了同一个位置的数字相加了。需要把先判断哈希表相应位置是否存在可以相加为target的数值之后给对应位置赋值。后来修改代码如下:
int* twoSum(int* nums, int numsSize, int target) {
int *index, i, *HashTable;
int min=nums[0], max, len;
index = (int *)malloc(sizeof(int)*2);
for(i = 1;i < numsSize;i++){
if(nums[i] < min) min = nums[i];
}
max = target - min;
len = max - min + 1;
HashTable = (int *) malloc(sizeof(int) * len);
for(i = 0;i < len;i++){
HashTable[i] = -1;
}
for(i = 0;i < numsSize;i++){
if(nums[i] - min< len){
if(HashTable[max - nums[i]] != -1){
index[0] = HashTable[max - nums[i]];
index[1] = i;
break;
}
HashTable[nums[i] - min] = i;
}
}
return index;
}
这次就成功了。但是不知道为何我的时间复杂度没提升多少,空间复杂度倒是蹭的一下上去了。后来自己再想,决定用结构体排序,排序之后从两端逼近target。这次的代码就在时间上有大提升,空间上也基本没有变化太大。
struct node {
int val;
int place;
}Node;
int cmp(const void* a, const void* b) {
return ((struct node*)a)->val - ((struct node*)b)->val;
}
int* twoSum(int* nums, int numsSize, int target) {
int i = 0;
int begin = 0, end = numsSize - 1;
int* index;
struct node* nodes = (struct node*)malloc(numsSize * sizeof(struct node));
for(i = 0; i < numsSize; i++) {
nodes[i].val = nums[i];
nodes[i].place = i;
}
qsort(nodes, numsSize, sizeof(struct node), cmp);
while(begin < end) {
if(nodes[begin].val + nodes[end].val == target) {
index = (int*)malloc(sizeof(int) * 2);
index[0] = nodes[begin].place;
index[1] = nodes[end].place;
break;
}
else if(nodes[begin].val + nodes[end].val > target)
end--;
else
begin++;
}
return index;
}
最后的结果:
这里如果使用leetcode-cn的话会变成52ms,看来可能两个网站真的有所不同?还是说是网络传输问题。。等以后学习了再看吧。