1.两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
第一次用了最笨蛋的方法,遍历一遍,对每个值在数组中搜索indexOf,时间很慢
第二遍用了map(),还是遍历并搜索,立马变快了……
**map键值对搜索性能很高!**O(1)
indexof原理
indexOf()根据传入的 pattern 的长度选择对应长度下效率最高的匹配算法
566.重塑矩阵
foreach
nums.forEach(item => {
item.forEach(v => {
aa.push(v)
})
})
forEach()
方法按升序为数组中含有效值的每一项执行一次 callback
函数
var matrixReshape = function(mat, r, c) {
var or=mat.length;
var oc=mat[0].length;
var arr=new Array(r);
if((or*oc)!=(r*c))
return mat;
var all=new Array();
mat.forEach(item=>{
item.forEach(v=>{
all.push(v);
})
})
for(var i=0;i<r;i++)
arr[i]=all.splice(0,c);
return arr;
};
array.splice()
切除splice(a,b)内的元素并返回这段数组
与slice相比,slice只是获取(a,b)的元素,并不切除它们
js的二维数组好难!
283.移动零
一次遍历
这里参考了快速排序的思想,快速排序首先要确定一个待分割的元素做中间点x,然后把所有小于等于x的元素放到x的左边,大于x的元素放到其右边。
这里我们可以用0当做这个中间点,把不等于0(注意题目没说不能有负数)的放到中间点的左边,等于0的放到其右边。
这的中间点就是0本身,所以实现起来比快速排序简单很多,我们使用两个指针i和j,只要nums[i]!=0,我们就交换nums[i]和nums[j]
![283_2.gif](https://pic.leetcode-cn.com/36d1ac5d689101cbf9947465e94753c626eab7fcb736ae2175f5d87ebc85fdf0-283_2.gif)
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
var moveZeroes = function(nums) {
var left=0;
for(var i=0;i<nums.length;i++) //注意这里为了不颠倒,两个初始值都应该是0!
{
if(nums[i]!=0)
{
let a=nums[i];
nums[i]=nums[left];
nums[left++]=a;
}
}
};
167.两数之和Ⅱ
给定一个已按照 升序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。
函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。
你可以假设每个输入只对应唯一的答案
![排除 i = 0 的全部解](https://pic.leetcode-cn.com/50d93bb2d2ce3e2985460586d4350e8205543965d9689632a20f5650dde3cb95.jpg)
如此,图解易得,取其加和后可容易判断,小了删行,大了删列
var twoSum = function(numbers, target) {
var left=0;
var right=numbers.length-1;
do{
let sum=numbers[left]+numbers[right];
if(sum>target)
right--;
else if(sum<target)
left++;
else
return [left+1,right+1];
}while(left!=right)
};
BUT时间不如map法。。。但思路可以借鉴,尤其是图解可以解决很多迷惑
88.合并两个有序数组
思路
从后向前数组遍历
因为 nums1 的空间都集中在后面,所以从后向前处理排序的数据会更好,节省空间,一边遍历一边将值填充进去
设置指针 len1 和 len2 分别指向 nums1 和 nums2 的有数字尾部,从尾部值开始比较遍历,同时设置指针 len 指向 nums1 的最末尾,每次遍历比较值大小之后,则进行填充
当 len1<0 时遍历结束,如果此时 nums2 中还有数据未拷贝完全,将其直接拷贝到 nums1 的前面,最后得到结果数组
一个重要的地方是
当nums1后面都是0时,不断覆盖的过程其实可以使前面的值盖掉后面的值,所以只用前面覆盖后面就行了,不用交换
while(l1>=0&&l2>=0)
{
if(nums1[l1]<=nums2[l2])
{
nums1[i]=nums2[l2];
l2--;
} else
{
nums1[i]=nums1[l1];
l1--;
}
i--;
}
sort方法的函数
var points = [40,100,1,5,25,10];
points.sort(
function(a,b)
{return a-b}
);
-
如果
Function(a, b)
小于 0 ,那么 a 会被排列到 b 之前;【升序】 -
如果
Function(a, b)
大于 0 , b 会被排列到 a 之前。【降序】
融合两个数组的方法
var vegetables = ['parsnip', 'potato'];
var moreVegs = ['celery', 'beetroot'];
// 将第二个数组融合进第一个数组
// 相当于 vegetables.push('celery', 'beetroot');
Array.prototype.push.apply(vegetables, moreVegs);
console.log(vegetables);
// ['parsnip', 'potato', 'celery', 'beetroot']
apply语法
func.apply(thisArg, [argsArray])
作用于一个函数!
第一个参数是作用的对象this,也就是说会改变this
第二个参数是用来apply加在后面的数组
push的陷阱!
如果push的参数是数组,它会将该数组作为单个元素添加,而不是将这个数组内的每个元素添加进去,因此我们最终会得到一个数组内的数组。
concat不中用!
concat
符合我们的需求,但它并不是将元素添加到现有数组,而是创建并返回一个新数组。