LeetCode算法学习之--分治--169.*多数元素*

152 阅读3分钟

「这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战

大家好今天给大家分享下一道 LeetCode 简单难度 的题目[169. 多数元素]

题目

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

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

image.png (图片截取leetcode)

分析

1.数组中找出出现次数大于n/2的那个数

2.并且返回那个数

解法

1.统计对象

2.分治

解法一:统计对象

思路
1.使用对象统计出现的频率
2.然后筛选出大于 Math.floor(nums.length / 2)的对象
*/
var majorityElement = function (nums) {
  if (!nums.length) return null;
​
  let res;
  const obj = {};
  //   统计出现频率
  for (const num of nums) {
    obj[num] ? obj[num]++ : (obj[num] = 1);
  }
​
  //   然后筛选出大于 Math.floor(nums.length / 2)的对象
  Object.keys(obj).forEach((key) => {
    if (obj[key] > Math.floor(nums.length / 2)) {
      res = key;
    }
  });
​
  return res;
};
​
/* 复杂度
时间 O(n)
空间 O(n)
*/

解法二:分治

思路
1.把数组nums 进行 一分为二的递归
2.如果为多数 那么在每层递归中 这个数最少都会出现一次,所以按这个思路有几个情况
    1.如果左边界left和右边界相同则直接返回这个元素
    2.如果数组左半边返回的值和数组右半边返回的值相同则直接返回这个元素
    3.如果不同 则统计整个区间中目标出现的频次,返回频次高的那个数
3.最后返回的值 则为多数
*/

var majorityElement = function (nums) {
  if (!nums.length) return null;

  //   统计区间中目标对象的频次
  function countNum(array, target) {
    return array.filter((item) => item === target).length;
  }

  function recur(arr) {
    //   如果左边界left和右边界相同则直接返回这个元素
    if (arr.length === 1) {
      return arr[0];
    }
    const mid = Math.floor(arr.length / 2);

    // 数组分成左区间和右区间
    const leftItem = recur(arr.slice(0, mid));
    const rightItem = recur(arr.slice(mid));

    // 如果相同则直接返回相同的值
    if (leftItem === rightItem) {
      return leftItem;
    }

    // 如果不同 则统计整个区间中目标出现的频次,返回频次高的那个数
    const leftCount = countNum(arr, leftItem);
    const rightCount = countNum(arr, rightItem);

    return leftCount > rightCount ? leftItem : rightItem;
  }

  return recur(nums);
};

/* 复杂度
时间 O(nlogn)
空间 O(logn)
*/

总结

今天这道题是主要是练习使用对象和分治的方式来求解数组中的多数

大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢

大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持

文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com

\