数组练习

01、查找某一个数出现的位置

题目描述

找出元素 item 在给定数组 arr 中的位置

输出描述:

如果数组中存在 item,则返回元素在数组中的位置,否则返回 -1

示例1

输入

[ 1, 2, 3, 4 ], 3

输出

2
function indexOf(arr, item) { 
    if (Array.prototype.indexOf){ 
        return arr.indexOf(item); 
    } else { 
        for (var i = 0; i < arr.length; i++){ 
            if (arr[i] === item){ 
                return i; 
            } 
        } 
    }      
    return -1; 
} 

2、求数组和

/**
 * 使用累加方法reduce
 * 这里列出了所有的函数形参
 * @param arr
 * @returns {*}
 */
var sum2 = function(arr) {
    return arr.reduce(function(prev, curr, index, arr) {
        return prev + curr;
    });
};

/**
 * 使用forEach遍历
 * @param arr
 * @returns {number}
 */
var sum3 = function(arr) {
    var sum = 0;

    arr.forEach(function(value, index, arr) {
        sum += value;
    }, 0);

    return sum;
};

function sum(arr) {
    return eval(arr.join("+"));
};

03、删除数组中=target的值

题目描述

移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组

示例1

输入

[1, 2, 3, 4, 2], 2

输出

[1, 3, 4]

不能够修改数组,显然最简单的,就是开辟一个临时数组,遍历一下原来的数组,如果不满足条件的就加入临时数组中去,最后返回tem即可

// 03 slice splice
function remove(arr,item){
    var newarr = arr.slice(0); // 直接从下标,为0开始,给一个新的数组,省去遍历的环节
    for(var i=0;i<newarr.length;i++){
        while(newarr[i] == item){
            newarr.splice(i,1);
        }
    }
    return newarr;
}
// 02 过滤函数
function remove(arr,item){
    return arr.filter(function(ele){
         return ele != item;
    })
}

slice以及splice 使用方式非常复杂,见到一个说一个,不要一口吃个大胖子

  • slice(start,end)
    • 返回的新数组,不影响原始数组!
    • 索引下标都是从0开始
    • 只有一个参数,从索引开始一直到最后
    • 两个参数,【start,end) 左开有闭
  • splice()
    • 两个参数 splice(start,num); 删除的索引,以及个数!

04、修改原来的数组 删除target值

function removeWithoutCopy(arr, target) {
    for (let i = 0; i < arr.length; i++) {
        while (arr[i] == target) {
            arr.splice(i, 1);
        }
    }
    return arr;
}
// 倒着循环就不用考虑 位置造成的影响 从后往前遍历删除,不会影响原本数组的元素位置。
function removeWithoutCopy(arr, item) {
    for(i=arr.length-1;i>=0;i--){
        if(arr[i] === item)
            arr.splice(i,1);   //splice() 方法向/从数组中添加/删除项目,然后返回被删除的项目。
    }
    return arr;
}


function removeWithoutCopy(arr, item) {
	while(arr.indexOf(item) != -1){
        arr.splice(arr.indexOf(item),1);
    }
    return arr;
}
// 这种方法也很赞 一个while循环就出来了,判断是否存在,存在了就删掉,不存在return;

05、末尾添加一个数,不能修改

题目描述

在数组 arr 末尾添加元素 item。**不要直接修改数组 arr**,结果返回新的数组

示例1

输入

[1, 2, 3, 4],  10

输出

[1, 2, 3, 4, 10]

push 显然后改变原来的数组

将原来数组中的数据放在一个临时数组中去可以使用slice(0),再使用push操作变量

function append(arr, item) {
    let tem = arr.slice(0);
    tem.push(item);
    return tem;
}
/**
 * 使用concat将传入的数组或非数组值与原数组合并,组成一个新的数组并返回
 * @param arr
 * @param item
 * @returns {Array.<T>|string}
 */
var append3 = function(arr, item) {
    return arr.concat(item);
};

function append(arr, item) {
    return [...arr,item]
}
  • concat()
    • 原始数组不会改变,创建一个新的数组
    • 有点类似,扩展运算符…

06、删除数组的最后一个元素

题目描述

删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组

示例1

输入

[1, 2, 3, 4]

输出

[1, 2, 3]

pop会改变原来数组,和上面思想一样,利用临时数组再执行pop()操作;

关键就是如何赋值:遍历; 扩展运算符,contact,slice() 都可以

//利用filter
function truncate(arr) {
    return arr.filter(function(v,i,ar) {
        return i!==ar.length-1;
    });
}
//利用push.apply+pop
function truncate(arr) {
    var newArr=[];
    [].push.apply(newArr, arr);
    newArr.pop();
    return newArr;
}
//利用join+split+pop    注意!!!:数据类型会变成字符型
function truncate(arr) {
    var newArr = arr.join().split(',');
    newArr.pop();
    return newArr;
}

//slice()方法返回指定数组的一个片段或者子数组,不改变原数组。本题要删除最后一个元素,
// 那就用该方法返回第0至倒数第二个的值
function truncate(arr) {
	return arr.slice(0,arr.length-1);
}

splice

几种操作都会修改原来的数组,返回值就是操作数组前两个参数的结果

  • 删除:当splice传入两个参数,第一个数开始删除的其实位置,第二个参数表示删除的个数
  • 插入:传入若干个参数,第一个表示开始插入的位置,第二个必须是0,既然是插入就不能是非零的数否则表示删除,接下来的参数表示要插入的数据
  • 修改/替换:是删除和插入的结合。第一个参数开始替换的下标,第二个参数删除的个数,替换的元素内容(先给删除然后再替换)
let arr  = [1,22,5,3,33,6];
// 删除 起始位置 删除的个数
let tem = arr.splice(1,2);
console.log(arr); // 1 3 33 6
console.log(tem); // 22 5

// 插入
let insert = arr.splice(1,0,66,66,66); // 在第一个位置插入 3个数
console.log(insert); // []
console.log(arr); // 1 66 66 66 3 33 6

// 修改 替换
let del = arr.splice(2,2,88,88);
console.log(del); // 66 66
console.log(arr); // 1 66 88 88 3 33 6

扩展运算符 […arr]

语法:… 将数组的每一项都拆分出来

应用

  1. 替代apply()求数组最大值
	let a = [1, 2, 3, 4];
	let maxValue1 = Math.max.apply(a);
	console.log(maxValue1); // ES5实现:4
	let maxValue = Math.max(...a);
	console.log(maxValue); // ES6实现: 4
  1. 复制数组
    ES5中复制数组,不会开辟新的空间,会指向同一个内存地址,改变任意一个数组,都会影响另一个数组。想要不改变的话可以使用concat方法 let c = a.concat();
	let a = [1, 2];
	let b = a;
	a[0] = 2;
	console.log(b); // 2 2
	
	let c = [...a];
	a[0] = 2;
	console.log(c); // 1 2
  1. 合并数组
	let a = [1, 2];
	let b = [3, 4, 5];
	let c = [...a, ...b];
	console.log(c); // [1, 2, 3, 4, 5]
	// ES5的方式
	let d = a.concat(b);
	console.log(d);
  1. 将伪数组转换成真正的数组
	let divs = document.querySelectorAll('div');
	console.log(divs);
	console.log([...divs]);

01、有序数组的平方

var sortedSquares = function(nums) {
    let res = [];
    for (let i = 0; i < nums.length; i ++) {
        res.push(nums[i] * nums[i]);
    }

    return res.sort(function(a, b) {
        return a - b;
    });
};

思想都一样,关键看怎么简化代码,使用ES6的新特性

var sortedSquares = function(nums) {
    let res = nums.map(item => item * item).sort((a,b)=> a - b);
    return res;
};

02、偶数在前,奇数在后

var sortArrayByParity = function(A) {

    let i = 0, j = A.length - 1;
    while (i < j) {
        while (A[i] % 2 === 0) i ++;
        while (A[j] % 2 === 1 ) j --;

        if (i < j) [A[i], A[j]] = [A[j],A[i]];
    }
    return A;
};

被震惊了!!!

// 01 排序
var sortArrayByParity = function(A) {
    return A.sort((a, b) => (a & 1) - (b & 1))
};
// 02 扁平化
var sortArrayByParity = function(A) {
    return A.reduce((p,v) => (p[v & 1].push(v),p),[[],[]]).flat();
};
// 03 为什么Push不进去
let res = [];
for (let i = 0; i < A.length; i++) {

    if (A[i] % 2 == 1) {
        console.log(`奇数:${A[i]}`);
        res.push(A[i]);
        // res.push(4);
    } else {
        console.log(`偶数:${A[i]}`);
        res.shift(A[i]);
    }
}
console.log(res);

03、按照奇数偶数排序II

var sortArrayByParityII = function(A) {
    const buckets = [[],[]];
    A.forEach(i => buckets[i % 2].push(i))
    return A.map((_, i) => buckets[i % 2].pop())
};

push可以一次,添加若干个参数!

var sortArrayByParityII = function(nums) {
    let res = [], odd = [], even = [];
    for (let i = 0; i < nums.length; i ++) {
        if (nums[i] % 2 == 1) { // 奇数
            odd.push(nums[i]);
        } else {
            even.push(nums[i]);
        }
    }

    for (let i = 0; i < nums.length / 2; i ++) {
        res.push(even[i],odd[i]);
    }
    return res;
};

04、最大连续1的个数

var findMaxConsecutiveOnes = function(nums) {

    let res = 0,maxCount = 0;
    for (let value of nums) {
        if (value === 1) {
            maxCount ++;
        } else {
            maxCount = 0;
        }
        res = Math.max(res, maxCount);
    }
    return res;
};

总是有简洁的做法:虽然看不懂

var findMaxConsecutiveOnes = function(nums) {
    return Math.max.apply(null,nums.join('').split('0').map((el)=>el.length))
};

05、翻转图像

这题没有想出来,

var flipAndInvertImage = function(image) {

    image.forEach(item => {
        item.reverse();
        item.forEach((every, index) => {
            item[index] = every ^ 1;
        })
    })
    return image;
};

06、三个数的最大乘积

似乎是一个结论,没做过我觉得我反应不过来

var maximumProduct = function(nums) {
    // 排序之后 
    // 01、最大的三个正数
    // 02、或者最小的两个负数 * 最大的正数

    nums.sort((a,b)=>a - b);
    let len = nums.length - 1;
    return Math.max(nums[0]*nums[1]*nums[len], nums[len - 2]*nums[len - 1]*nums[len]);
};

07、数组拆分

拆成n 对,取得里面的最小值,是的每一对里面的最小值之和最大!

  • 排序之后, 每前两队是最优的集合,并且每次删掉偶数
var arrayPairSum = function(nums) {

    nums.sort((a, b) => a - b);
    let res = 0;
    for (let i = 0; i < nums.length; i += 2) {
        res += nums[i];
    }
    return res;
};

08、判断是否存在相同元素

var containsDuplicate = function(nums) {

    let flag = false;
    for (let i = 0; i < nums.length; i ++) {
        if (nums.indexOf(nums[i]) !== nums.lastIndexOf(nums[i])) {
            flag = true;
        }
    }
    return flag;
};

09、是否存在重复元素02

var containsNearbyDuplicate = function(nums, k) {

    const set = new Set();
    for (let i = 0; i < nums.length; i ++) {
        let x = nums[i];
        if (set.has(x)) return true;
        set.add(x);
        if (set.size > k) {
            set.delete(nums[i- k]);
        }
    }
    return false;
};

10、第三大的数

  • 数组利用set去重之后再转换成数组!!
  • 排序之后的
var thirdMax = function(nums) {
    // 来一遍去重
    let res = [...new Set([...nums])];
    if (res.length <= 2) return Math.max(...res);
    res.sort((a, b) => a - b);
    return res[res.length - 3];
};

11、至少是其他数的二倍

var dominantIndex = function(nums) {

    // 和上一个题一样 找出最大的两个数a, b
    // 假设a 是最大的,如果 a > 2 * b  true
    // else -1;
    let maxValue = Math.max(...nums);
    let maxIndex = nums.indexOf(maxValue);
    nums.splice(maxIndex,1); // 将最大的元素删掉之后 求第二大的元素
    let secondMax =  Math.max(...nums);
    if (maxValue >= secondMax * 2) return maxIndex;
    else return -1;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值