JavaScript中已经为我们封装好了较为完善的数组(自动扩容,允许存放不同类型的数据)
数组中间插入和删除性能较低,但是查找速度快(下标查找)
方法名 | 说明 | 返回值 |
---|---|---|
unshift(参数1…) | 头增,修改原数组 | 返回新的长度 |
push(参数1…) | 尾增,修改原数组 | 返回新的长度 |
shift() | 头删,修改原数组 | 返回删除元素值 |
pop() | 尾删,修改原数组 | 返回删除元素值 |
方法名 | 说明 | 返回值 |
---|---|---|
reverse() | 翻转数组,修改原数组 | 返回新数组 |
sort() | 直接使用,会将数字当成字符串,只看第一位;回调使用,排序;修改原数组 | 返回新数组 |
// 不能直接使用arr.sort,会按照字符串排序,即按照第一位数字排序
// 必须在里面加个function确定顺序
var arr=[1,20,60,7];
arr.sort() //1,20,60,7
arr.sort(function(a,b){
return(a-b);//升序排列
return(b-a);//降序排列
});
方法名 | 说明 | 返回值 |
---|---|---|
indexOf(参数) | 从前向后找,只找一个 | 第一个满足条件的索引号,不存在返回-1 |
lastIndexOf(参数) | 从后向前找,只找一个 | 第一个满足条件的索引号,不存在返回-1 |
includes(参数,开始位置) | 查找是否存在 | true/false |
方法名 | 说明 | 返回值 |
---|---|---|
concat() | 连接两个或多个数组,不影响原数组 | 返回新数组 |
slice() | 数组截取slice(begin,end),不影响原数组 | 返回被截取项目的新数组 |
filter(item=>item.done) | 不影响原数组 | 返回新数组 |
splice() | 数组更新splice(begin,个数,item1…itemX)第三个参数可选,不填即为截取,会影响原数组 | 返回被删除项目的新数组 |
// 注意:slice()顾头不顾尾
var arr=[1,20,60,7];
var newArr = arr.slice(0,3)
console.log(newArr);// [1,20,60]
将类数组或可遍历对象转化为真正的数组
Array.from(可遍历对象名)
无返回值,对原数组没有影响
arr.forEach(function(value,index,arr) {})
// value当前正在遍历的元素
// index当前正在遍历元素的索引
// arrobj整个数组
支持return返回,对原数组没有影响
array.map(function(value,index,arr), thisValue)
// value 必选。当前元素的值
// index 可选。当前元素的索引值
// arr 可选。当前元素属于的数组对象
// thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。
// 返回一个新数组
// 等同于
function myMap(fn){
//this是调用此方法的数组
let newArr = []
for(let i = 0;i<this.length;i++){
let result = fn(this[i],i,this)
newArr.push(result)
}
return newArr
}
// callback有三个参数。
// value:每一次迭代查找的数组元素。
// index:每一次迭代查找的数组元素索引。
// arr:被查找的数组。
所有项都满足条件,返回true
只要有一项满足条件,就会返回true
查找符合条件的元素,找到第一个值返回,找不到返回undefined
查找符合条件的元素,找到第一个值返回其索引,找不到返回-1
注意:find()返回的是值,indexOf()返回的是索引
findIndex比indexOf更强大一些,可以通过回调函数查找对象数组,但indexOf可以指定开始查找位置的索引
方法名 | 说明 | 返回值 |
---|---|---|
toString() | 把数组转换为字符串,逗号分隔每一项 | 返回一个字符串 |
join(“分隔符”) | 把数组中所有元素转换为一个字符串 | 返回一个字符串 |
var containsDuplicate = function(nums) {
let arr = []
for(let i = 0 ; i<nums.length;i++){
if(arr.indexOf(nums[i])==-1){
arr.push(nums[i])
}else{
return true
}
}
return false
};
最开始想的是直接暴力,将所有结果存在一个数组中,比较得出最大值,但是这样会超过数组存储限制
因此我们使用动态规划
var maxSubArray = function(nums) {
let res = nums[0]
let sum = 0
for(const num of nums){
// 如果和sum大于0,代表对之后有益,继续向后计算
if(sum>0){
sum += num
}else{
// sum小于或等于0,对后面计算不利,直接从当前值开始计算
sum = num
}
// 用旧的res比较新的sum,将较大的赋给res
res = Math.max(res,sum)
}
return res
};
// 思路主要是用数组es6的新方法
// 对n==0和m==0的情况单独进行判断
// 其他即为正常情况,我们使用splice更新数组
// 使用sort排序
var merge = function(nums1, m, nums2, n) {
if(n==0){
return nums1
}else if(m==0){
Object.assign(nums1,nums2)
}else{
nums1.splice(m,nums1.length-m,...nums2)
nums1.sort((a,b)=>{
return(a-b)
})
}
};
最基本的双重for循环就不写了
// 使用map
// 遍历数组,用目标值-数组的值求出需要的值
// 将数组中的值作为value,位置作为key存入map
// 找到符合要求的value,就返回对应的key
var twoSum = function(nums, target) {
let map = new Map()
for(let i=0; i<nums.length; i++){
const number = target - nums[i]
if(map.has(number)){
return [map.get(number),i]
}else{
map.set(nums[i],i)
}
}
};
// 双重for循环,遇到相同的就push进结果
// 同时删除第二个数组的该元素并跳出本次循环
var intersect = function(nums1, nums2) {
const res = []
for(let i=0;i<nums1.length;i++){
for(let j=0;j<nums2.length;j++){
if(nums2[j] == nums1[i]){
res.push(nums2[j])
nums2.splice(j,1)
break
}
}
}
return res
};
// 哈希map
// 使用map,key为nums1的元素,value为该元素出现次数
// 当有次数时遇到与nums2相同的元素,就push到结果中
// 并将次数-1
var intersect = function(nums1, nums2) {
const map = new Map()
const res = []
for(num1 of nums1){
if(map[num1]){
map[num1]++
}else{
map[num1] = 1
}
map.set(num1,map[num1])
}
for(num2 of nums2){
if(map.get(num2)>0){
res.push(num2)
map.set(num2,--map[num2])
}
}
return res
};
注意prices的长度,嵌套for循环必超时
// 贪心算法
// 遍历prices,用当前值减去之前遍历中遇到的最小值等到当前的最大值
// 比较res和当前最大值谁大,将大的赋给res
var maxProfit = function(prices) {
if(prices.length<2) return 0
let max = 0
let minPrice = prices[0]
for(let i=0; i<prices.length;i++){
max = Math.max(max,prices[i]-minPrice)
minPrice = Math.min(prices[i],minPrice)
}
return max
};