1、Algorithm 一道算法题
给你一个整数数组
nums,判断是否存在三元组[nums[i], nums[j], nums[k]]满足i != j、i != k且j != k,同时还满足nums[i] + nums[j] + nums[k] == 0。请你返回所有和为
0且不重复的三元组。注意: 答案中不可以包含重复的三元组。
这道题可以用排序 + 双指针解决。 首先对数组排序,这样有利于对三数集合进行去重。 然后从头到尾遍历数组,每次循环中,以当前元素作为三数中的第1个数字,以当前元素后面一位元素作为三数中的第2位数字,以最后一位元素作为三数中的第3位元素。
其中当前循环中,指向第2位元素和第3位元素这2个左右指针再依据当前的和进行相应方向的移动。
具体地,当三数之和目前是0时,把当前元素和左右2个指针的值加入结果集合;当和为负时,由于当前数组是递增,因此需要移动左指针向右指针方向移动;当和为正时,需要移动右指针向左指针方向移动。
其中还有一项要求是去重,在遍历元素以及移动左右指针时,由于数组是排序数组,因此值相同的元素会左右相邻,因此通过判断当前指针的上一个元素和目前元素的值是否相等,可以快速去重,通过继续移动指针来忽略重复元素。
具体 JS 代码实现:
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function(nums) {
let n = nums.length;
if(!nums ||n < 3){
return []
}
// 升序排序
nums.sort((a,b)=>a-b)
let result = []
for(let i=0;i<n;i++){
// 如果第一个数大于0,由于是递增数组后面的和不可能小于0,所以退出循环
if(nums[i] >0 ){
break;
}
// 去重
if(i>0 && nums[i] === nums[i-1]){
continue;
}
let L = i + 1;
let R = n -1;
while(L < R ){
let sum = nums[i] + nums[L] + nums[R];
if(sum === 0 ){
result.push([nums[i],nums[L],nums[R]])
while(L < R && nums[L] === nums[L+1]){
// 去重
L++;
}
while(L < R && nums[R] === nums[R-1]){
// 去重
R--;
}
L++;
R--;
}else if(sum<0){
L++;
} else{
R--;
}
}
}
return result
};
2、Review 读一篇英文文章
重新阅读了盒模型的MDN介绍
一个元素使用
display: inline-block,实现我们需要的块级的部分效果:
设置
width和height属性会生效。
padding,margin, 以及border会推开其他元素。
3、Technique/Tips 分享一个小技术
在移动端,为了增加点击区域的大小,可以通过增加 padding 或者透明 border 的方法。 其中推荐 border 方法。假设我们的图标是使用工具生成的,那么 background-position 就是限定死的值。若再使用 padding 撑开间距,就会遇到定位不准确的问题。但是,使用透明 border 增加点击区域,则无此问题,只要合并时留下足够的间距就可以了。
.icon-clear{
width:16px;
height:16px;
border:11px solid transparent;
}
此时,点击区域大小从 1616 提升到 3838。
4、Share 分享一个观点
前端开发的工作由浅入深依次聚焦在应用技术,工程技术,领域技术和基础技术。
大量的前端从业者都位于应用技术层,为各个业务生产出各式各样的商业应用。
少数的高级前端在应用开发之余,也投身在工程技术研发上,为广大从业者保驾护航。
较少的前端高手,基于兴趣驱动,在各个细分领域做着大量抽象工作,为前端行业提供通用解决方案。
极少的前端顶级专家,除了以上的工作之外,还参与着技术标准的制定,默默地推动着行业的发展。