学习内容
数组与字符串
这是leedcode中一本免费的学习书籍,讲的是基础的数组与字符串,正如这本书的简介所介绍的那样,“大多数面试问题都属于这个范畴”,在这里用文章记录一下我(也就是小白)的学习过程,既学习这本书,也学习如何把这类博客写好。
学习重点
学了第一章数组简介后,对于其中学习重点是什么的问题,我觉得两小节的内容都算的上是重点,一个是介绍适用于所有编程语言的抽象理论,另一个是数组基本的增删查改(CRUD BOY(^_^))。
学习心得
第一章的3个习题中,第一个是如何寻找数组的中心索引,我的思路是先对整个数组求和,再遍历数组,对减掉当前元素后值的一半判断奇偶,并与前面元素的和进行比较,可以得到结果。(PS:因为最近学 js比较多,所以代码是用 js写的。)
对于第二个搜索插入位置的问题,我的思路是先判断首尾端点,再折半查找,判断当前元素与前后元素的关系,可以得到结果。
我对第三个“合并区间”的问题最感兴趣。
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]] 输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入:intervals = [[1,4],[4,5]] 输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
作者:力扣 (LeetCode) 链接:leetcode-cn.com/leetbook/re…
限于能力不够的原因,代码无论是时间还是空间,都没能超过10%。但还是是简单的记录一下我在做这道题时的思路,留待我以后有所提升后回头看看。
下面是大致思路:
graph TD
Push --> Sort --> Return
在一开始声明start和end变量,作为返回区间的两个端点值。
Push:把题目中的“假区间”稍微转化的更“细致”一点。(这也是时间开销最大的地方)
简单来说,“假区间”就是类似题目中[1,4]这种只给出了区间的两个端点,中间的数值(比如1.1,1.2,2,3等等)不存在的数组。
“细致”是将原区间转化为更偏向数学意义上的区间,在这里以0.5(由于重叠的问题,不能是1)为递增值,将[1,4]转化成了[1,1.5,2,2.5, ... ,3.5,4]。
最后把里面全部的值(不是单单两个区间端点)全部压入一个新的数组。
Sort: 将上面的数组排序。
Return: 在这一步将遍历排序后的数组,如果当前元素与下一个元素的值相差大于0.5,就重置两个端点,并将重置前的区间压入需要返回的数组中,遍历完成,结果也就全部得到了。
最后是代码,有一些限于篇幅没有写出来的小细节在里面,做一个完整的记录。
* @param {number[][]} intervals
* @return {number[][]}
*/
var merge = function(intervals) {
let nums = []
let result = []
let start
let end
intervals.forEach((val) => {
for(var i = val[0]; i <= val[1]; i = i + 0.5){
nums.push(i);
}
})
nums = nums.sort((a,b) => a - b)
start = nums[0]
nums.forEach((num,index) => {
if(nums[index + 1] - num > 0.5) {
end = nums[index]
result.push([start,end])
start = nums[index + 1]
}
})
result.push([start,nums[nums.length - 1]])
return result
};
相比于另外两个习题,这个题目我没能想出一个可以用一次遍历解决问题的方法,这个代码时间复杂度大致为O (n*n) ,当然最后的排名也说明了这个问题,哈哈。
边写边看,我感觉还可以将排序后的数组去重优化一下,不过这样依然没有质的改变,感觉提升不大,甚至去重的开销相比减少的遍历开销更大也有可能。
总结:
做习题还是很有用的,一方面锻炼了思维,另一方面也熟悉了语言(比如Js的sort函数特点)。如果有幸被刷到,欢迎指点。