算法打卡第二十三天

45 阅读2分钟
  1. 剑指 Offer 39. 数组中出现次数超过一半的数字
  2. 剑指 Offer 66. 构建乘积数组

剑指 Offer 39. 数组中出现次数超过一半的数字

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

题意理解 找出数组中出现超过一半的数,次数一定存在

  1. 声明两个变量,一个用来存储当前数,一个用来计算当前抵消出现次数最多的数
  2. 遍历结束,返回当前抵消后的数

摩尔投票法: 查找输入数据中重复的数据超过一般,必须超过一半,等于不算,一定存在这个数

var majorityElement = function(nums) {
    let count = 0;
    let currentNum = 0;
    nums.forEach(num => {
        if (count < 1) {
            currentNum = num;
        }
        num === currentNum ? count++ : count--
    })
    return currentNum
};

哈希表统计法

var majorityElement = function(nums) {
    let map = new Map()
    for (let i = 0; i < nums.length; i++) {
        if (map.has(nums[i])) {
            map.set(nums[i], map.get(nums[i]) + 1)
        } else {
            map.set(nums[i], 1)
        }
    }
    let value;
    map.forEach((val, key) => {
        if (val >= (nums.length) / 2) {
            value = key;
        }
    })
    return value;
}

剑指 Offer 66. 构建乘积数组

给定一个数组 A[0, 1, …, n-1],请构建一个数组 B[0, 1, …, n-1],其中B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

题意理解: B数组中的数据等于A中所有数据的乘积然后除以自生,因为不能使用除法,所以此方法弃用 再计算B[i]的时候,可以将A[i]看成1与其他A中数据的乘积 可以列出一个表格,看成1的数据就是一条斜线,将表格分成左下和右上两个部分,这样就可以找出规律

  1. 左下区域,可以使用递推一次计算,及B1[i] = A[0] * A[1] ... A[i-1]
  2. 右上区域,可以使用倒叙递推一次计算,及B2[0] = A[i-1] * A[i-2] ... A[0]
  3. 最终结果B[i] = B1[i] * B2[i]
B\A12345
1 1 2345
21 1 345
312 1 45
4123 1 5
51234 1

表格分区

var constructArr = function (a) {
    if (!a.length) return [];
    let arr = [1]
    for (let i = 1; i < a.length; i++) {
        arr[i] = arr[i - 1] * a[i - 1]
    }
    console.log(arr);
    let temp = 1;
    for (let i = a.length - 1; i >= 0; i--) {
        arr[i] = arr[i] * temp;
        temp *= a[i]
    }
    return arr;
};