为了账号安全,请及时绑定邮箱和手机立即绑定

投稿015期 | 【五道题学习算法】数据结构与算法 - Set

这些都是数据结构与算法,一部分方法是团队其他成员实现的,一部分我自己做的,有什么其他实现方法或错误,欢迎各位大佬指点,感谢。

一、集合是什么?与它相关数学概念有哪些


解题:

1.集合定义:

集合(Set)是一种包含不同元素的数据结构。集合中的元素称为成员,集合最重要的两个特点:

  • 集合中的成员是无序;

  • 集合中不存在相同成员;

即:无序且唯一。

2.集合相关的数学概念:

集合的概念,如数学中一个由大于或等于0的整数组成的自然数集合, N = { 0, 1, 2, ...}

还有如空集,表示不包含任何元素的集合。
并且也有并集,交集,差集等操作。

二、请实现一个集合,并实现以下方法

add(value):向集合添加一个新的项。
delete(value):从集合移除一个值。
has(value):如果值在集合中,返回 true,否则返回 false。
clear():移除集合中的所有项。
size():返回集合所包含元素的数量。与数组的 length 属性类似。
values():返回一个包含集合中所有值的数组。


解题:

class Sets {
  constructor(){
    this.items = {}
  }
  has(value){
    // return value in this.items
    return this.items.hasOwnProperty(value)
  }
  add(value){
    if(!this.has(value)) {
      this.items[value] = value
      return true
    }
    return false
  }
  delete(value){
    if(!this.has(value)){
      delete this.items[value]
      return true
    }
    return false
  }
  clear(){
    this.items = {}
  }
  size(){
    const values = this.values()
    return values.length
  }
  values(){
    return Object.keys(this.items)
  }
}

三、请实现集合的并集、交集、差集、子集操作

  • 并集(union):对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。
  • 交集(intersection):对于给定的两个集合,返回一个包含两个集合中共用元素的新集合。
  • 差集(difference):对于给定的两个集合,返回一个包含所有存在于第一个集合且不存在于第二个集合的元素的新集合。
  • 子集(subset):验证一个给定集合是否是另一个集合的子集。

解题:

/**
* union 并集
* @param {Object} otherSet 其他集合
*/
Sets.prototype.union = function(otherSet){
  let result = new Sets(),
  current = this.values(),
  other = otherSet.values()
  for(let i = 0; i < current.length; i++){
    result.add(current[i])
  }
  for(let i = 0; i < other.length; i++){
    result.add(other[i])
  }
  return result
}

/**
* intersection 交集
* @param {Object} otherSet 其他集合
*/
Sets.prototype.intersection = function(otherSet){
  let result = new Sets(),
  current = this.values()
  for(let i = 0; i < current.length; i++){
    if(otherSet.has(current[i])){
      result.add(current[i])
    }
  }
  return result
}

/**
* difference 差集
* @param {Object} otherSet 其他集合
*/
Sets.prototype.difference = function(otherSet){
  let result = new Sets(),
  current = this.values()
  for(let i = 0; i < current.length; i++){
    if(!otherSet.has(current[i])){
      result.add(current[i])
    }
  }
  return result
}

/**
* subset 子集
* @param {Object} otherSet 其他集合
*/

Sets.prototype.subset = function(otherSet){
  let result = new Sets(),
  current = this.values()
  if(this.size() > otherSet.size()) return false
  for(let i = 0; i < current.length; i++){
    if(!otherSet.has(current[i])){
      return false
    }
  }
  return true
}

四、给定两个数组,编写一个 intersection() 函数来计算它们的交集

使用示例如下:

const nums1 = [1, 2, 2, 1];
const nums2 = [2, 2];
const nums3 = [4, 9, 5];
const nums4 = [9, 4, 9, 8, 4];

intersection(nums1, nums2); // [2]
intersection(nums3, nums4); // [9, 4]

提示:输出结果中的每个元素是唯一的,可以不考虑输出结果的顺序。


解题:

function intersection(arr1, arr2){
  if(!Array.isArray(arr1) || !Array.isArray(arr2)) return []
  let create = function(arr){
  let sets = new Sets()
  arr.map(item => sets.add(item))
    return sets
  }
  let Sets1 = create(arr1)
  let Sets2 = create(arr2)
  let result = Sets1.intersection(Sets2)
  return result.values()
}

五、给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集

使用示例如下:

const nums = [1, 2, 3];
subsets(nums);

// 输出以下结果:
[
  [3],
  [1],
  [2],
  [1, 2, 3],
  [1, 3],
  [2, 3],
  [1, 2],
  []
]

解题:

目前网络上的最优解:

function subsets(nums){
  if(!nums || !Array.isArray(nums)) return []
  function diff (num, vec) {
    let tmp = vec.slice(0)
    result.push(tmp)
    for (let i = num; i < len; i++) {
      vec.push(nums[i])
      diff(i + 1, vec)
      vec.splice(-1)
    }
  }
  const len = nums.length
  let arr = [], result = []
  diff(0, arr)
  return result
}

穷举法:

function subsets(nums){
  if(!nums || !Array.isArray(nums)) return []
  let result = [[]],
  len = nums.length
  if(len === 0) return result
  for(let i = 0; i < len; i++){
    let l = result.length
    let num = nums[i]
    let array = [num]
    for(let j = 0; j < l; j++){
      let tmparray = result[j].concat(array)
        result.push(tmparray)
      }
    }
    return result
  }

关于

作者:王平安
来源:前端自习课

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消