剑指Offer——数组中数字出现的次数(JS实现)

简介: 剑指Offer——数组中数字出现的次数(JS实现)

前言

掘金团队号上线,助你 Offer 临门! 点击 查看详情

题目描述

image.png

解题思路

思路一:使用哈希表(空间复杂度不满足)

  • 将键表示为数组的元素,值表示为出现的次数
// 方法1:使用Map数据结构
var singleNumbers = function(nums) {
    const m = new Map();
    for (let v of nums) {
        if (m.has(v)) {
            m.set(v,m.get(v) + 1)
        } else {
            m.set(v,1);
        }
    }
    result = [];
    for (let v of m) {
        if (v[1] === 1) {
            result.push(v[0])
        }
    }
    console.log(result);
    return result;
};
作者:Always_positive
链接:https://juejin.cn/post/6948663990512238606
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

思路2:使用位运算(多个for循环:不满足空间复杂度的要求)

  • 因为题目中说了除了两个数字出现一次外,其余数字都出现了两次,凡是出现了两次,做异或运算都为0,所以全部进行遍历异或得到的值一定是那两个只出现一次的数字。
  • 我们根据全部遍历异或的到的结果比如是0111,从最后一位1可以看出,这两个只出现1次的数字的最后一位一定是不同的,所以我们根据这个特征来进行分组。
  • 最后一位为1的分为1组,为0的分为1组。
  • 两个组分别进行异或,得到的值然后返回就是最终的结果。可以在纸上演算下。
// 使用位运算的方法
var singleNumbers = function(nums) {
    let temp = 0;
    let temp2 = 0;
    let temp3 = 0;
    for (let v of nums) {
        temp = temp ^ v;
    }
    let temp1 = temp.toString(2);
    let flag = 1;
    for (let i = temp1.length-1;i >= 0;i--) {
        console.log(temp1[i]);
        if (temp1[i] === '0') {
            flag = flag + 1;
        } else {
            break;
        }
    }
    // 遍历每个数组,将数组中的值转为二进制
    const result = []
    for (let v of nums) {
        result.push(v.toString(2));
    }
    console.log(result);
    let arr1 = [];
    let arr2 = [];
    for (let v of result) {
        if (v[v.length-flag] === '1') {
            arr1.push(v);
        } else {
            arr2.push(v);
        }
    }
    console.log(flag);
    console.log(arr1);
    console.log(arr2);
    for (let i in arr1) {
        arr1[i] = parseInt(arr1[i],2)
    }
    for (let i in arr2) {
        arr2[i] = parseInt(arr2[i],2)
    }
    console.log(arr1);
    console.log(arr2);
    for (let v of arr1) {
        temp2 = temp2 ^ v;
    }
    for (let v of arr2) {
        temp3 = temp3 ^ v;
    }
    console.log(temp2,temp3);
    return [temp2,temp3];
};
作者:Always_positive
链接:https://juejin.cn/post/6948663990512238606
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最终解决方案(符合题目要求)

  • 使用位运算
  1. 首先让数组的所有元素依次进行异或运算,得到的值从右往左第一个1的位置就是两个只出现1次元素的不同的位置。
  2. 使用变量记录从右往左第一个1的位置。
  3. 将第二步得到的变量与数组中的每个元素进行与运算,可以将上述的数组分为两组
  4. 这两组分别进行全体异或,得到两个值然后返回就是题目要的只出现一次的数字。

代码

var singleNumbers = function(nums) {
    let temp = 0;
    let a = 0;
    let b = 0;
    for (let v of nums) {
        temp = temp ^ v;
    }
    console.log(temp);
    // 判断从右往左第几位是1
    let One_Location = 1;
    while ((temp & One_Location) === 0) {
        One_Location = One_Location << 1;
    }
    for (let v of nums) {
        if ((One_Location & v) === 0) {
            a = a ^ v;
        } else {
            b = b ^ v;
        }
    };
    return [a,b];
};
作者:Always_positive
链接:https://juejin.cn/post/6948663990512238606
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关文章
|
29天前
|
自然语言处理 前端开发 JavaScript
🛠️ JavaScript数组操作指南:20个精通必备技巧🚀
本文详细介绍了 JavaScript 中的 20 个高效数组操作技巧,涵盖了从基本的添加、移除元素,到数组转换和去重等高级操作。强调了不可变性的重要性,提供了清晰的代码示例,帮助开发者编写更整洁和高效的代码。无论是新手还是经验丰富的开发者,这些技巧都将显著提升您的编码能力,使您在项目中更具竞争力。
21 2
|
1月前
|
JavaScript 前端开发 测试技术
JS都有哪些操作数组的方法
JS都有哪些操作数组的方法
20 3
|
1月前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
31 1
|
1月前
|
JavaScript 前端开发 API
JS中数组的方法flat()怎么用
JS中数组的方法flat()怎么用
13 0
|
JavaScript 前端开发
用javascript的isNan()函数,可以判断是否为数字
var getstockid = $.trim($("#SearchString").val()); if (!isNaN(getstockid)) alert('是数字!'); else alert('不是数字!');  学习交流群:364976091
881 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
95 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
118 4
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物援助平台附带文章源码部署视频讲解等
81 4
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的宠物交易平台附带文章源码部署视频讲解等
72 4
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的大学生入伍人员管理系统附带文章源码部署视频讲解等
92 4