剑指offer day23 数学(简单)

day23题目:剑指 Offer 39. 数组中出现次数超过一半的数字剑指 Offer 66. 构建乘积数组

知识点:数组、哈希、前缀和,难度为简单、中等

学习计划链接:「剑指 Offer」 - 学习计划

题目知识点难度
剑指 Offer 39. 数组中出现次数超过一半的数字数组哈希表分治计数\简单
剑指 Offer 66. 构建乘积数组数组前缀和中等

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

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

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

限制:

1 <= 数组长度 <= 50000

注意:本题与主站 169 题相同:https://leetcode-cn.com/problems/majority-element/

思路及代码

思路一:利用哈希,当出现次数超过一半就立刻返回,但这样空间复杂度和时间复杂度都为O(n)

var majorityElement = function(nums) {
    let m = new Map()
    for ( let i = 0; i < nums.length; i++) {
        if (m.has(nums[i])) {
            let t = m.get(nums[i])
            if(t+1 > Math.floor(nums.length / 2))
                return nums[i]
            m.set(nums[i],t + 1)
        } else m.set(nums[i], 1)
    }
    return nums[nums.length-1]
};

思路二:在大神Krahets题解中提到的 摩尔投票法,主要要注意两个推论,详见题解。

  • 推论一: 若记 众数 的票数为 +1非众数 的票数为 -1 ,则一定有所有数字的票数和 > 0
  • 推论二: 若数组的前 a 个数字的 票数和 = 0 ,则 数组剩余 (n−a) 个数字的 票数和一定仍 > 0 ,即后 (n-a) 个数字的 众数仍为 x

ps:这个思路真是清奇。没想到

var majorityElement = function(nums) {
    let vote = 0;
    let candidate = null;
    for (let num of nums) {
        if (vote === 0) 
            candidate = num;
        vote += (num === candidate) ? 1 : -1;
    }
    return candidate;
};

剑指 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]。不能使用除法。

示例:

输入: [1,2,3,4,5]
输出: [120,60,40,30,24]

提示:

  • 所有元素乘积之和不会溢出 32 位整数
  • a.length <= 100000

思路及代码

这题就有些类似之前字节校园的题目:冲刺春招-精选笔面试66题大通关day14:135. 分发糖果 的弱化弱化版了,从左往右初始化下数组 l, l[i]表示i左侧所有数字的乘积,而第二次遍历从右侧开始,算出右侧乘积和后直接加到数组上。

/**
 * @param {number[]} a
 * @return {number[]}
 */
var constructArr = function(a) {
    let res = new Array(a.length)
    let l = [1]
    for (let i = 1; i < a.length; i++) 
        l.push(l[i-1] * a[i-1])
    let r = 1;
    for (let i = a.length - 1; i >= 0; --i) { // 右侧乘积 & res计算
        if(i != a.length-1)
            r *= a[i+1]
        res[i] = l[i] * r
    }
    return res
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

余cos

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

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

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

打赏作者

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

抵扣说明:

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

余额充值