JS中的数组(含leetcode例题)<持续更新~>

本文详细介绍了JavaScript数组的基本特性和常用方法,包括增删改查、连接操作、遍历与条件判断,并结合LeetCode题目实战演练了查找重复元素、最大子数组和、合并有序数组等技巧。深入探讨了数组转字符串和解决算法问题的实例。
摘要由CSDN通过智能技术生成

数组

基本特性
  • 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)第三个参数可选,不填即为截取,会影响原数组返回截取部分的新数组
// 注意:splice()、slice()都是顾头不顾尾
    var arr=[1,20,60,7];
    var newArr = arr.slice(0,3)
    console.log(newArr);// [1,20,60]
遍历
  • Array.from()

将类数组或可遍历对象转化为真正的数组

Array.from(可遍历对象名)
  • forEach(function(value,index,arr) {})

无返回值对原数组没有影响

arr.forEach(function(value,index,arr) {})
// value当前正在遍历的元素
// index当前正在遍历元素的索引
// arrobj整个数组
  • map(function(value,index,arr) {})

支持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:被查找的数组。
  • every(callback)

所有项都满足条件返回true

  • some(callback)

只要有一项满足条件,就会返回true

  • find(callback)

查找符合条件的元素,找到第一个值返回找不到返回undefined

  • findIndex(callback)

查找符合条件的元素,找到第一个值返回其索引找不到返回-1

注意:find()返回的是值,indexOf()返回的是索引

findIndex比indexOf更强大一些,可以通过回调函数查找对象数组,但indexOf可以指定开始查找位置的索引

数组转字符串
方法名说明返回值
toString()把数组转换为字符串,逗号分隔每一项返回一个字符串
join(“分隔符”)把数组中所有元素转换为一个字符串返回一个字符串
leetcode例题
217. 存在重复元素
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
};
53. 最大子数组和

最开始想的是直接暴力,将所有结果存在一个数组中,比较得出最大值,但是这样会超过数组存储限制

因此我们使用动态规划

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
};
88. 合并两个有序数组
// 思路主要是用数组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)
        })
    }
};
1. 两数之和

最基本的双重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)
        }
      }
  };
350. 两个数组的交集 II
// 双重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
};
121. 买卖股票的最佳时机

注意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
};
566. 重塑矩阵

遇到这个题,我首先想到的思路就是先将二维数组转一维,再进行后面的操作

几种将二维数组转一维的方法(数组扁平化)

// 方法一:遍历,使用concat拼接
const arr1 = [[1,2],[3,4]]
var arr2 = []
for(let i=0;i<arr1.length;i++){
  arr2 = arr2.concat(arr1[i])
}

// 方法二:使用apply()
// apply的第一个参数用来修改this指向,传入一个空数组即可
// apply的第二个参数为一个数组,可以作为其调用函数的参数使用(即[].concat调用了apply,使用了参数arr1)
// apply会解开数组参数的第一层[[1,2],[3,4]]-->[1,2],[3,4]
// 此时使用concat即可完成拼接
var arr2 = [].concat.apply([],arr1);

// 方法三:flat(参数)实现数组扁平化
// 参数的意思是需要扁平化的层数
    const arr1 = [[1,2],[3,4]]
    const arr2 = arr1.flat(1) //二维-->一维,扁平化1层

解题代码

var matrixReshape = function(mat, r, c) {
    // 数组拍平
    let arr = mat.flat()
    let res = []
    if(r*c != arr.length){
        return mat
    }else{
        // r行
        for(let i=0;i<r;i++){
            let item = []
            // c列
            for(let j=0;j<c;j++){
                item.push(arr.shift())
            }
            res.push(item)
        }
        return res
    }
};

// 调用api,继续简化
function matrixReshape(mat, r, c) {
    const arr = mat.flat()
    const res = []
    if(r*c != arr.length) return mat
    for(let i = 0; i < r; i++){
        // splice截取数组,返回值为截取部分的数组
        res.push(arr.splice(0,c));
    }
    return res;
};
118. 杨辉三角
// 二维数组动态规划
var generate = function(numRows) {
    let arr = [[1]]
    // 遍历每行
    for(let i=0;i<numRows;i++){
        arr[i] = []
        arr[i][0] = 1 // 每行首尾都是1
        arr[i][i] = 1
        for(let j=1;j<i;j++){
            // 动态规划,拆分子问题
            arr[i][j] = arr[i-1][j-1]+arr[i-1][j]
        }
    }
    return arr
};
36. 有效的数独

为了便于理解,我将横向、纵向和9宫格区域分开判断

  • 判断方式:遍历每块区域,如果map中没有该元素,就set进去,如果有,说明重复,返回false
  • 遍历方式:横向和纵向的遍历比较简单,不再说明
    每个9宫格主要是通过
    x = 3*Math.floor((i/3))+Math.floor((j/3))
    y = Math.floor(3(i%3))+Math.floor((j%3))来得出每次遍历九宫格的坐标
// 暴力
var isValidSudoku = function(board) {
    // 判断每行
    for(let row of board){
        let map = new Map()
        for(let i=0;i<9;i++){
            if(row[i] != "."){
                if(!map.get(row[i])){
                    map.set(row[i],1)
                }else{
                    return false
                }

            }
        }
    }

    // 判断每列
    for(let j=0;j<9;j++){
       let map = new Map()
       for(let col of board){
           if(col[j] != "."){
               if(!map.get(col[j])){
                   map.set(col[j],1)
               }else{
                   return false
               }
           }
       } 
    }

    // 判断3*3宫
    for(let i=0;i<9;i++){
        let map = new Map()
        for(let j=0;j<9;j++){
            let x = 3*Math.floor((i/3))+Math.floor((j/3)) 
            let y = Math.floor(3*(i%3))+Math.floor((j%3))
            if(board[x][y] != "."){
                if(!map.get(board[x][y])){
                    map.set(board[x][y],1)
                }else{
                    return false
                }
            } 
        }
    }
    return true
};
73. 矩阵置零
// 将值为0的横纵坐标存起来
// 再遍历将对应的行列变为0
var setZeroes = function(matrix) {
    let row = []
    let col = []
    for(let i=0;i<matrix.length;i++){
        for(let j=0;j<matrix[0].length;j++){
            if(matrix[i][j]==0){
                row.push(i)
                col.push(j)
            }
        }
    }
    row.forEach(item=>{
        for(let i=0;i<matrix[0].length;i++){
            matrix[item][i] = 0
        }
    })
    col.forEach(item=>{
        for(let j=0;j<matrix.length;j++){
            matrix[j][item] = 0
        }
    })
    return matrix
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
你可以使用以下方法对二维向量vector<vector<int>>进行排序: 1. 使用STL的sort函数进行排序。引用提到了一些排序算法,比如堆排序(heap_sort),希尔排序(shell_sort),选择排序(select_sort)和快速排序(quick_sort_swap)。你可以根据需要选择其一个算法对vector<vector<int>>进行排序。 2. 如果你想在创建二维向量时就进行排序,你可以使用引用的方法通过vector创建二维数组,并在创建时对其的元素进行排序。 3. 如果你已经创建了一个二维向量,你可以使用引用的方法使用resize函数对二维向量进行重新分配,并在重新分配时对其的元素进行排序。 无论你选择哪种方法,都可以对二维向量vector<vector<int>>进行排序。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vectorstring和vectorint](https://blog.csdn.net/toCVer/article/details/122484732)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [leetcode2sumc-Code-Storm2019:力密码2019](https://download.csdn.net/download/weixin_38700430/19937142)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的战斗鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值