【Leetcode 169 】 多数元素——投票算法要把我迷倒了

 

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

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

示例 1:

输入:nums = [3,2,3]
输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2

提示:

  • n == nums.length
  • 1 <= n <= 5 * 104
  • -109 <= nums[i] <= 109

进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。

/** 排序实现 */
function majorityElement(nums: number[]): number {
  /** 由于排序,而且题目中说明一定有 出现次数大于 nums.length / 2 的值 */
  /** 所以 奇数情况下 [1, 2, 3, x, 5, 6, 7] ,无论是前半部分还是后半部分,符合条件的值的位置都会有x这个值,否则数量无法达标*/
  /** 偶数情况下,[1,2,x,y,5,6],无论是前半部分还是后半部分,符合条件的值的位置都会有x,y这两个值,否则数量无法达标 */
  let index = Math.floor(nums.length / 2);
  nums.sort((a, b) => a - b);
  return nums[index];
}

/** Boyer-Moore投票算法 */
/**
 *  思想:将数组的值分为两类,一类为 结果值(出现次数大于 nums.length / 2),且称为x,而另一类就是其余的值,称为y
 *  首先 x的数量 一定是大于 y的数量,同理,x数量 - a > y数量 - a  ,满足这个公式,则可以通过x与y相互抵消来获取结果,因为最后剩下的一定是x
 *
 */
function majorityElement(nums: number[]): number {
  /** 结果值,假设其为0(初始为任何数值都可以) */
  let candidate = 0;
  /** count 用于保留x的数量,如果count为0,则证明candidate的值并不是真正的结果值。则改变candidate的值 */
  let count = 0;
  for (const num of nums) {
    /** 当count为0时,表示x的数量为0,candidate并不是我们想要的值,赋值为下一个num */
    if (count === 0) {
      candidate = num;
    }
    /**
     * 目前candidate的值假设为真正的结果值
     *  如果num = candidate,则表示x值的数量多了一个,则+1,
     *  否则表示y值的数量多了一个,则-1
     */
    count += candidate === num ? 1 : -1;
  }
  /** 因为题目中假设了一定有值 出现次数大于 length / 2 的,所以在x类与y类相互抵消中,最后剩下的一定的x类,则值为candidate */
  return candidate;
}

 

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。它的时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度。 KMP算法的核心思想是利用已知信息来避免不必要的字符比较。具体来说,它维护一个next数组,其中next[i]表示当第i个字符匹配失败时,下一次匹配应该从模式串的第next[i]个字符开始。 我们可以通过一个简单的例子来理解KMP算法的思想。假设文本串为S="ababababca",模式串为P="abababca",我们想要在S中查找P的出现位置。 首先,我们可以将P的每个前缀和后缀进行比较,得到next数组: | i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | | --- | - | - | - | - | - | - | - | - | | P | a | b | a | b | a | b | c | a | | next| 0 | 0 | 1 | 2 | 3 | 4 | 0 | 1 | 接下来,我们从S的第一个字符开始匹配P。当S的第七个字符和P的第七个字符匹配失败时,我们可以利用next[6]=4,将P向右移动4个字符,使得P的第五个字符与S的第七个字符对齐。此时,我们可以发现P的前五个字符和S的前五个字符已经匹配成功了。因此,我们可以继续从S的第六个字符开始匹配P。 当S的第十个字符和P的第八个字符匹配失败时,我们可以利用next[7]=1,将P向右移动一个字符,使得P的第一个字符和S的第十个字符对齐。此时,我们可以发现P的前一个字符和S的第十个字符已经匹配成功了。因此,我们可以继续从S的第十一个字符开始匹配P。 最终,我们可以发现P出现在S的第二个位置。 下面是KMP算法的C++代码实现:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值