LeetCode初体验

来源:互联网 发布:锐捷网络校招 编辑:程序博客网 时间:2024/05/17 08:46

LeetCode初体验

最近工作不是那么繁忙,后知后觉发现了LeetCode(刷过的大神可以绕道了),知呼看了下感觉挺有意思的,就自己注册了账号试着解决一下问题。下面把第一次加入LeetCode的过程记录下,官网:https://leetcode.com/

这里写图片描述

首先右上角,Sign up注册一个账号,比较简单;然后Sign in进行登录。然后点击左上角的Problems,查看问题。


这里写图片描述

列表里可以根据难易程度排序,不过按照知呼大神的经验,分类别来做题比较好,在某个专题类别上做出感觉先。所以根据上边的Category,我选择算法(Algorithms)。截图我只做了第一个简单的题—Two Sum \笑哭,感觉确实挺有意思的。从右侧可以看到,现在总共有701个题目


这里写图片描述

点击某个题进去,有题目描述和例子数据,红色圈部分可以选择你需要使用的语言。编辑框里边已经给出了函数/方法的定义,直接实现它就行了。上边部分由Submissions能看到自己的提交记录,有讨论区和解决方案等,可以先去参考下解决方案的思路,然后自己根据思路做出实现来。


这里写图片描述

编辑框右下角有Run Code可以进行测试,代码有错的话会进行报错提示。当Your answer和Expected answer相同时,则此用例测试通过,最下边有通过此用例所使用的时间。但是实际严格测试不止这一组数据,所以左边可以勾选Custom Testcase自己填写输入参数来进行测试。感觉测试差不多了可以点击右边Submit Solution进行提交。提交后系统会用他们自己的所有用例测试一遍,当系统所有用例测试通过时,会显示绿色的Accepted字样,提交测试通过。


这里写图片描述

提交测试结束后可以看到大家的结果对比。上边提示,有19个测试用例,用时3ms。第一个图,x坐标为时间,越靠左越好;y坐标为分布量,具体是人数还是提交量没搞懂。可以点击其中的柱形图来查看每个结果使用的代码,可以拿来参考学习。第二个图就是第一个图的整体视图,鼠标可以进去拖放来控制第一个图的显示区域。(两个图都是显示的当前提交所使用的语言的结果分析,没有其他语言结果掺进来。)


总结:根据问题的Solution提示,可知道简单的方案时间复杂度都偏高,所以需要更优的算法来解决它,然后大家一起来比比看谁的方法比较好。第一个题主要考虑时间复杂度,不知道有没有其他题是考虑其他方面的,后续再看吧。



下面是我提交的第一个twoSum的源码,个人见解,不喜勿喷:

/*这个时间复杂度为O(n^2),不推荐。但是好理解。int* twoSum(int* integers,int size,int target){    int* ret = (int*)malloc(2 * sizeof(int));    for(int i=0; i < size; i++){        for(int j=i+1;j < size && j != i; j++){            if(integers[i] + integers[j] == target){                ret[0] = i;                ret[1] = j;                break;            }        }    }    return ret;}*/int* twoSum(int* integers,int size,int target) {    int* ret = (int*)malloc(2 * sizeof(int));    int min = 0x7fffffff;    int i = 0;    for (i = 0; i < size; i++) {        if (integers[i] < min) //找到最小值            min = integers[i];    }    //构造一个hash数组,里边存放数字的下标    int needMax = target - min; //另外一个加数在hash里边数据最大的数,没必要到target那么多,因为是两个数的和    int hashLen = 0;    if(min > 0) //当最小为正数时,这个min可以忽略来看        min = 0;    hashLen = needMax - min + 1;//最大值和最小值的差,就是这个target和的两个加数所在范围。    int* hash = (int*)malloc(hashLen * sizeof(int));    for (i = 0; i < hashLen; i++) {        hash[i] = -1; //先全部置为-1    }    //查找  /*  for(i = 0; i < size; i++){        if(integers[i] >= hashLen)//当某个下标值比hash要包括的大,则不填入hash.如[0,4,3] 3这种,其实值用Hash下标到3就可以了,但是先取出4来,越界。            continue;        //其实思想就是找到target-integers[i]这两个数的差,它标记上,表示有值。而下边检测integers[i]这个减数里是否标记,有的话那就是上边的差了。        //因为上边的continue,所以target- integers[i]的integers[i]和下边的integers[i]肯定不一样,俩个不一样的数加起来为target,那就是我们要找的那两个数。        if(hash[integers[i]] != -1){//如果找到某个格子里存放的是有下标的。而这个格子是通过integers[i]确定的一个其中一个数和target的差,那就是存在的数了            ret[0] = i < hash[integers[i]] ? i : hash[integers[i]]; //拿最小的那个            ret[1] = i + hash[integers[i]] - ret[0]; //获得另外一个大点的            free(hash);            break;        }        hash[target- integers[i]] = i; //其实判断的就是target-integers[i] = integers[i]这个式子是否成立,而两个integers[i]中的i是不相等的。    } */    //以上是均为正数的情况,当有负数在integers里边时,integers[i]得到负数,则hash直接出错,所以这时候需要整体增大min,让下标成为正数    for(i = 0; i < size; i++){        if(integers[i] - min >= hashLen)             continue;        if(hash[integers[i] - min] != -1){            if(target- (integers[i] - min) == integers[i] - min){//有两个相同的数                ret[0] = i < hash[target - integers[i] - min] ? i : hash[target - integers[i] - min];                ret[1] = i + hash[target - integers[i] - min] - ret[0];            }else{                ret[0] = i < hash[integers[i] - min] ? i : hash[integers[i] - min];                ret[1] = i + hash[integers[i] - min] - ret[0];            }            free(hash);            break;        }        hash[target- integers[i] - min] = i;    }    return ret;}