前言

这是本人第一次参加由Datawhale举办的组队学习活动,这个活动每月一次,之前也一直关注,但未亲身参与过,这次看到活动中有一项组队刷LeetCode,恰逢本人正在准备考研复试机试,便欣然加入以求有所收获和提升。
同时,这也是本人第一次在CSDN写文章,希望在此记录并向大家分享自己在学习过程中总结的知识和收获的感悟,也可以在此和大家谈论遇到的问题,向诸位优秀的CSDNer们学习,我们共同进步!

ε≡٩(๑>₃<)۶ 一心向学

活动简介

天池Leetcode基础训练营
适合leetcode小白,同时也可以学习到一些数据结构与算法的知识,适合初学者快速入门,需要一点点的编程基础。
2022年2月14日-2022年3月10日
o 知识讲解+例题解析+习题实践,完整入门Leetcode刷题之旅
o 24天训练营助教陪你答疑解惑
o 排名/周赛拿证书,给你的简历履历添砖加瓦

活动地址
https://tianchi.aliyun.com/specials/promotion/2-9?spm=5176.15228502.0.0.34c079bfkDKMxB

Datawhale组队学习
Datawhale是一个活跃于高校的开源组织,每月举办的组队学习活动致力于营造互促的学习氛围和纯粹的学习环境,提供开源免费的学习内容和学习规划,方便大家有监督和无监督学习,从而帮助到更多学习者成长。截止今日,Datawhale已经开源50多门学习内容,涉及编程、数据科学、cv、nlp、强化学习和推荐系统6大模块,这源自每一个开源贡献者的参与。

开源地址
https://github.com/datawhalechina/team-learning

Task01数组

知识点总结

  1. 数组的定义
    数组是具有一定顺序关系的若干对象组成的集合,组成数组的对象成为数组元素。
    它可以存储一个 固定大小相同类型 元素的顺序集合。
    数组的元素也可以是数组,这样就得到了多维数组。

  2. 数组的存储
    数组是由连续的内存位置组成,即在物理存储层面是使用一片连续的存储空间。
    最低的地址对应第一个元素,最高的地址对应最后一个元素。 即按顺序连续存储。
    这样的好处是我们可以利用索引对数组元素进行随机存取,而不足则是数组空间固定,不易扩充或减少,容易造成溢出或空间浪费。

  3. 数组元素的访问
    数组的存储按照行优先(C、C++、C#)或列优先(Forturn)的原则进行。
    可以利用以下公式计算得到数组中任一下标所存元素的位置,当然在C语言中我们可以直接利用下标对数组元素进行访问。(考研数据结构里面还是比较喜欢考下面这种计算的)
    以下数组声明分别为 type a[n]; type a[m][n]; type a[m][n][l];

    一维数组:Loc(a[i]) = Loc(a[0]) + i x c
    二维数组:Loc(a[i][j]) = Loc(a[0][0]) + (i x n + j) x c
    三维数组:Loc(a[i][j][k]) = Loc(a[0][0][0]) + (i x n x l + j x l + k) x c
    以上公式中 c 即代表数组中单个元素大小,可以利用 sizeof(a[0]) 得到,也是数据类型type的大小

例题

  1. Leetcode1 两数之和
    这是一道很简单的题,很直接的思路就是暴力解法,利用二重循环穷举数组中两元素之和,找到满足的两元素返回下标即可,这样解答的时间复杂度是O(N2);
    此外,可以将数组先排序,再分别从头尾开始夹逼。
    Leetcode的官方题解还提供了利用哈希表的解法,这样可以将时间复杂度降低至O(N)。
  2. Leetcode16 最接近的三数之和
    这是一道中等难度的题,也可以用暴力解法求解,即考虑直接使用三重循环枚举三元组,找出与目标值最接近的作为答案,但是时间复杂度将达到O(N3);
    Leetcode的官方题解中给出的解法是双指针法,即首先将数组元素升序排列,假设数组的长度为 n,我们需要的答案由 a、b、c 三个数得到,可以先枚举 a,它在数组中的位置为 i,然后在位置 [i+1,n) 的范围内利用双指针法枚举 b 和 c。具体为令指针 low 指向 i+1,即 b 的起始位置,另指针 high 指向 n-1,即 c 的起始位置;利用 a+b+c 与 target 比较的结果来更新答案,即若 a+b+c > target,就使low++,若a+b+c < target,就使high–,而当 a+b+c = target 时即可直接返回答案。

作业题

1 Leetcode27 移除元素
这道题看似很简单,但在代码实现时需要注意细节,且题目中还特别注明需要原地移除待删元素,即使用O(1)的额外空间。
对于数组我们没法像链表那样直接删除某个结点,只能用其他值来覆盖待删元素的原始值。同时为了让数组中剩余元素都集中在数组前部,即需要对数组元素进行移动,如果按照这样的思路,则每找到一个等于 val 的元素,都要将其后所有元素向前移动,即num[i]=num[i+1],时间复杂度为O(N2)。
优化的算法是,利用双指针,让 i 指向当前将要处理的元素,j 指向下一个将要赋值的位置。如果 i 指向的元素不等于 val,则是需要保留的元素,就将 i 指向的元素复制到 j 指向的位置,然后将 i 和 j 同时右移;如果 i 指向的元素等于 val,则需要被覆盖,此时 i 不动,j 右移一位。当 i 遍历完整个数组后,j 的值即为结果数组的长度。
以上算法实现如下,另,以上算法还可以继续优化,即利用头尾双指针,具体可参考Leetcode官方题解。

int removeElement(int* nums, int numsSize, int val){int j=0;for(int i=0; i<numsSize; i++){if(nums[i]!=val)nums[j++]=nums[i];}
//  printf("%d\n",j);
//  for(int i=0; i<j; i++)
//      printf("%d ",nums[i]);return j;
}

2 Leetcode26 删除有序数组中的重复项
这道题与上一题极为相似,这里的重复项其实即为上一题中的val,又因为数组有序,所以重复项必定是连续的。利用双指针法,用 i 指向需保留的元素的存储位置,用 j 当前遍历元素的位置,当数组元素大于0时,数组中至少包含一个元素,因此 nums[0] 必定保留,所以从下标 1 开始删除重复元素。当 j 遍历到与保留元素不相等的元素时,即要保留,将其赋给 i,并将 i 和 j 向后移动;当 j 指向元素与 i 所指元素相等时,即为重复项,继续向后移动 j。
注意,这里的 i 指向的是结果数组中最后一个元素的位置,因此结果数组实际长度为 i+1 。
Leetcode官方题解中解法与此相同,但其具体实现时时用 nums[j] 与 nums[j-1] 相比。

int removeDuplicates(int* nums, int numsSize){int i=0;for(int j=1; j<numsSize; j++){if(nums[i]!=nums[j])nums[++i]=nums[j];}return i+1;
}

3 Leetcode15 三数之和
这道题与例题中的第2题也是大同小异,相信那道题看懂了的话,这道题的思路也会很透彻,我就不再赘述。
这里重点说一下用C语言的代码实现,如果是使用C++,那么丰富的STL可以很方便的操作和存储三元组,但是C语言则需要用到指针和内存管理相关的知识。
相信很多初学C语言的同学看到提交代码的函数头已是一头雾水,还好我不久前刚好看过这块儿相关的内容,还可以理解一部分,但是也有些不懂的地方,这里给大家推荐一下一本C语言学习手册。

回到这道题,首先需要明确的是,我们的结果是由若干三元组组成的一个数组,即一个二维数组,其中每个元素为含有三个元素的一维数组。再看这个函数头,
int** threeSum,该函数的返回值为结果二维数组的起始位置,即第一个三元组中第一个元素的位置;int* returnSize,表示一共有多少个三元组,需要在起始时赋值0,若不在第一行赋值便会报错,原因位置,还请知晓的大佬指教;int** returnColumnSizes,表示二维数组中每个元素(即一维数组)的大小,可见他也是一个二重指针,具体原因我也不知。

再看内存申请:

int** ret = (int**)malloc(sizeof(int*) * numsSize * numsSize);
ret[*returnSize] = (int*)malloc(sizeof(int) * 3);

以上两句分别是为作为结果的二维数组 ret 和 ret 中每新增的一个三元组 ret[*returnSize] 申请空间。
C语言中数组名等同于起始地址,也就是说,数组名就是指向第一个成员的指针,所以 ret[] 就等同于* ret; 而 int** ret 就等同于int ret[][],但是后者声明方法需要指出二维数组的大小,且声明后得到的内存空间将无法再进行改变,所以需要使用前者来动态申请一片空间。

*returnColumnSizes = (int*)malloc(sizeof(int) * numsSize * numsSize);
(*returnColumnSizes)[*returnSize] = 3;

至于这两句,我也着实存在疑问,不懂为什么要这样申请空间以及赋值,还请朋友们指点。

int cmp(const void* a, const void* b){return (*(int*)a - *(int*)b);
}
int** threeSum(int* nums, int numsSize, int* returnSize, int** returnColumnSizes){*returnSize = 0;if(numsSize < 3)return NULL;qsort(nums, numsSize, sizeof(int), cmp);int** ret = (int**)malloc(sizeof(int*) * numsSize * numsSize);*returnColumnSizes = (int*)malloc(sizeof(int) * numsSize * numsSize);for(int i=0; nums[i] <= 0 && i<numsSize-2; i++){if(i > 0 && nums[i]==nums[i-1])continue;int low = i+1, high = numsSize-1;while(low < high){int sum = nums[i] + nums[low] + nums[high];if(sum == 0){ret[*returnSize] = (int*)malloc(sizeof(int) * 3);ret[*returnSize][0] = nums[i];ret[*returnSize][1] = nums[low];ret[*returnSize][2] = nums[high];(*returnColumnSizes)[*returnSize] = 3;(*returnSize)++;while(low < high && nums[low] == nums[++low]);while(low < high && nums[high] == nums[--high]);}else if(sum < 0) low++;else high--;}}
//  printf("%d\n", *returnSize);return ret;
}

结语

第一次写文章必然存在很多不足,以上内容若有错误,还请朋友们多多指点;另外由于赶时间,写的比较匆忙,算法也没有做图解,说的可以也不太清楚,而且还有些疑问自己也未解决,还请大家包涵。

Leetcode学习成长记:天池leetcode基础训练营Task01数组相关推荐

  1. Leetcode学习成长记:天池leetcode基础训练营Task02链表

    Task02 链表 知识点总结 单链表 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.即逻辑上位置相邻的元素其物理位置不一定相邻. 链表中的数据是以结点来表示的,每个 ...

  2. java在线学习系统源码_java学习成长之路(基础,源码,项目,实战)

    获取一下学习资源请关注微信公众号:Java编程指南 我为自学编程的或初学java的小伙伴们准备了一整套完整的学习资源和文章,还有我自己在自学路上的一些总结和学习线路,希望能帮到小伙伴们,如果有什么疑问 ...

  3. 猿创征文|我的四个月Java学习成长之路——从基础到框架再到项目

    个人简介:  >

  4. 《大学生前端成长记》 ---JavaScript基础 --冒泡(Bubble)和取消冒泡(cancelBubble)

    Javascript的冒泡,原来是这样! 事件传递有两种方式:冒泡与捕获. 冒泡(Bubble) 举个例子,我碰了你的手,你的手属于你,所以我也就碰了你. 就是这么简单,如果还不明白,那就看下面 &l ...

  5. Datawhale 阿里云天池LeetCode基础训练营 c++ Code

    Datawhale & 阿里云天池LeetCode基础训练营 Task1: 数组 课后习题 1. 删除有序数组中的重复项(Easy) 题意: 给一个有序的数组,其中有若干数是重复出现的,如 [ ...

  6. 【组队学习】【34期】阿里云天池在线编程训练营

    阿里云天池在线编程训练营 航路开辟者:陈信达.杨世超.赵子一.马燕鹏 领航员:武帅.初晓宇.叶前坤.邱广坤.朱松青 航海士:宁彦吉.肖桐.汪超.陈信达.杨世超.赵子一.武帅.初晓宇.叶前坤.邱广坤.朱 ...

  7. Leetcode学习之动态规划

    动态规划学习内容 1. 动态规划理论基础 什么是动态规划 动态规划的解题步骤 动态规划应该如何debug 2. 斐波那契数 思路 3. 爬楼梯 思路 4. 使用最小关系爬楼梯 思路 5. 不同路径 思 ...

  8. python 开课了_解答你学习Python的困惑,《Python小白成长记》开课啦

    原标题:解答你学习Python的困惑,<Python小白成长记>开课啦 继<Python轻松学>和<Python-turtle图形编程入门>两门Python课程后, ...

  9. LeetCode学习-查找2-合并版

    LeetCode学习-查找 几个基本数据结构 一,查找表 349,求公共元素 242,判断两字符串是否字母相同 202,快乐数问题 290,模式匹配(需理清思路) 205,同构 451,对出现频率排序 ...

  10. 飞桨图像分类零基础训练营学习笔记和心得体会

    飞桨图像分类零基础训练营学习笔记和心得体会 参加了百度一线AI工程师为大家讲解图像分类模型部署.课程内容包含Paddle2.0转静合一轻松导出模型.Paddle Lite环境准备.Paddle Lit ...

最新文章

  1. NLP汉语自然语言处理原理与实践
  2. MSRA20周年研究趋势文章|图像识别的未来:机遇与挑战并存
  3. amazeui学习笔记--css(基本样式)--样式统一Normalize
  4. 前序遍历(递归、非递归)、层序遍历(递归、非递归)
  5. 2049 : 压死骆驼的最后一根稻草 (规律)
  6. python中如何调用或修改元组中的元素_python 元组的使用方法
  7. python3.6 websocket异步高并发_在Python3.6上的websocket客户端中侦听传入消息时出现问题...
  8. 四二拍用音符怎么表示_每个音符都是赞美歌拍子分析 0基础识简谱每日必看
  9. 淘宝客API网站在这两年里经历了不少次百度K站风波
  10. SAP License:我应该怎么学习SAP?
  11. PHP语言之表单基础
  12. react-ssr之路由配置
  13. 【机器学习算法】线性回归算法
  14. 安装dump1090
  15. C报错ld returned 1 exit status可能的原因
  16. python实现火车票查询
  17. 2020高考倒计时html,2020高考倒计时的励志说说
  18. 【CSS】CSS实现三角形(一)
  19. LDA and QDA
  20. Java实现莱布尼兹问题

热门文章

  1. 编程验证足球预测算法的准确概率
  2. html及css经典面试题
  3. Linux vi命令详解与使用教程
  4. “外行”带你看国标38900-2020(一)
  5. Labview视觉模块安装
  6. 人工智能:一种现代方法 第四版 翻译序言
  7. Markdown编辑器语法之代码高亮、标记和文字颜色
  8. eeglab和matlab,哪位大神会eeglab
  9. 鞋城模板+html,西安锦绣鞋城整合营销策划方案
  10. 数据中心 服务器管理规范,互联网技术详解 | 新时代数据中心管理标准Redfish