LeetCode初体验

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值