数据结构与算法之数组: Leetcode 914. 卡牌分组 (Typescript版)

这篇具有很好参考价值的文章主要介绍了数据结构与算法之数组: Leetcode 914. 卡牌分组 (Typescript版)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

卡牌分组

  • https://leetcode.cn/problems/x-of-a-kind-in-a-deck-of-cards/

描述

  • 给定一副牌,每张牌上都写着一个整数。

  • 此时,你需要选定一个数字 X,使我们可以将整副牌按下述规则分成 1 组或更多组:

    • 每组都有 X 张牌。
    • 组内所有的牌上都写着相同的整数。
  • 仅当你可选的 X >= 2 时返回 true。

示例 1:

输入:deck = [1,2,3,4,4,3,2,1]
输出:true
解释:可行的分组是 [1,1],[2,2],[3,3],[4,4]

示例 2:

输入:deck = [1,1,1,2,2,2,3,3]
输出:false
解释:没有满足要求的分组。

提示:

  • 1 <= deck.length <= 1 0 4 10^4 104
  • 0 <= deck[i] < 1 0 4 10^4 104

算法实现

1 )方案 1

function hasGroupsSizeX(deck: number[]): boolean {
    // 边界情况
    if (deck.length < 2) return false
    // 对牌进行排序,无所谓顺序
    deck.sort()
    let flag: boolean = true // 最终的返回结果
    let arr: number[][] = []
    for (let i = 0, len = deck.length, tmp = []; i < len; i ++) {
        tmp.push(deck[i])
        // 基于当前的i逐个对比,判断是否和arr[i] 相同, 注意这个边界值
        for (let j = i + 1; j <= len; j ++) {
            // 相同时,逐一加入tmp进行存储
            if (deck[i] === deck[j]) {
                tmp.push(deck[i])
            } else {
                // 不相同时
                // 数组长度不满足2的边界值处理
                if (tmp.length < 2) {
                    return false
                }
                arr.push([].concat(tmp)) // 注意:这里数组是一个新的对象会被push到result中, 不能直接用tmp这个引用对象
                tmp.length = 0 // 清空临时数组
                i = j - 1 // 将i的下标移动到 j-1
                break // 跳出此层循环
            }
        }
        if (!flag) {
            break
        }
    }
    let result: number[] = arr.map(item => item.length) // 二维数据编程存储长度的一维数组
    result = [...new Set(result)]  // 对数组去重,减少重复运算
    // 求是否是最大公约数函数
    const isGcd = (arr: number[]) => {
        // 所有的数组都是一个长度
        if (arr.length === 1) {
            return true
        }
        const gcd = (x: number,y: number) => !(x % y) ? y : gcd(y, x % y) // 求两个数的最大公约数
		let final = 1 // 初始化最大公约数为1
		while (arr.length > 1) {
			let num1 = arr[0], num2 = arr[1];
			final = gcd(num1, num2)
			if(final === 1) {
				return false
			} else {
				arr.splice(0,2, final) // // 迭代,继续求最大公约数
			}
		}
		return final !== 1
	}
    return isGcd(result)
}
  • 上述写法很长,基于正常的思维来处理的,两层循环进行聚类分组
  • 之后简化数组存储,从存储原数据变更为存储同一数值类型的卡牌长度
  • 然后,对所有数组进行去重操作,留下一个唯一的数组
  • 在这个唯一数组中求最大公约数,如果最大公约数为1,则返回false, 否则返回true
  • 需要注意的是:一些边界值的处理,有些情况开启边界值检测可以提前结束程序
  • 这个程序的缺点是:复杂,维护性不佳

2 )方案 2文章来源地址https://www.toymoban.com/news/detail-430682.html

function hasGroupsSizeX(deck: number[]): boolean {
    // 边界判断
    if (deck.length < 2) return false
    // 存储每张卡牌的总数
    let result: number[] = []
    // 临时存储对象
    const tmp: object = {}
    // 使用对象来存储累加当前数据的值
    deck.forEach(item => {
        tmp[item] = tmp[item] ? tmp[item] + 1 : 1
    })
    // 将最终的结果存放到一个数组中
    for (let v of Object.values(tmp)) {
        result.push(v)
    }
    // 对数组进行去重
    result = [... new Set(result)]
    // 求两个数的最大公约数
    const gcd = (x: number,y: number) => !(x % y) ? y : gcd(y, x % y)
    while (result.length > 1) {
        const a = result.shift() // 移除当前数组第一个 并把返回值赋给 a
        const b = result.shift() // 移除当前数组第一个 并把返回值赋给 b
        // 得到当前最大公约数
        const v = gcd(a, b)
        if (v === 1) {
            return false
        } else {
            result.unshift(v) // 将当前得到的新约数存入数组开头,进入下一个循环
        }
    }
    return result.length ? result[0] > 1 : false
};
  • 上述程序,通过修改数据结构,将处理数据的复杂度大大降低
  • 注意下,上述记录同一数值的卡牌数量的object和while循环处理的精妙之处

到了这里,关于数据结构与算法之数组: Leetcode 914. 卡牌分组 (Typescript版)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据结构与算法之堆: Leetcode 215. 数组中的第K个最大元素 (Typescript版)

    数组中的第K个最大元素 https://leetcode.cn/problems/kth-largest-element-in-an-array/ 描述 给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。 你必须设计并实现时间复杂度为 O(n) 的算法解决此

    2024年02月07日
    浏览(53)
  • LeetCode 刷题 数据结构 数组 485 最大连续1的个数

    给定一个二进制数组  nums  , 计算其中最大连续  1  的个数。 示例 1: 示例 2: 提示: 1 = nums.length = 105 nums[i]  不是  0  就是  1.   参看bilibli视频-up主 爱学习的饲养员,讲解的很清晰。 手把手带你刷Leetcode力扣|各个击破数据结构和算法|大厂面试必备技能【已完结】-

    2024年02月15日
    浏览(51)
  • 【算法 & 高级数据结构】树状数组:一种高效的数据结构(二)

    🚀 个人主页 :为梦而生~ 关注我一起学习吧! 💡 专栏 :算法题、 基础算法、数据结构~赶紧来学算法吧 💡 往期推荐 : 【算法基础 数学】快速幂求逆元(逆元、扩展欧几里得定理、小费马定理) 【算法基础】深搜 数据结构各内部排序算法总结对比及动图演示(插入排序

    2024年03月26日
    浏览(85)
  • 【算法 & 高级数据结构】树状数组:一种高效的数据结构(一)

    🚀 个人主页 :为梦而生~ 关注我一起学习吧! 💡 专栏 :算法题、 基础算法~赶紧来学算法吧 💡 往期推荐 : 【算法基础 数学】快速幂求逆元(逆元、扩展欧几里得定理、小费马定理) 【算法基础】深搜 树状数组 (Binary Indexed Tree,BIT)是一种数据结构,用于高效地处理

    2024年03月11日
    浏览(68)
  • 数据结构与算法(一): 稀疏数组

    在五子棋游戏或类似的游戏中,我们可以把整个棋盘想象成是一个有规律的二维数组,其值由0、1、2三个数字组成,0代表空白区域,1代表白子,2代表黑子。这种情况:即当一个数组中大部分元素为0或者为同一值时,存储该数组数据可以使用稀疏数组来对原始数组进行精简,

    2024年02月11日
    浏览(47)
  • 数据结构与算法 | 数组(Array)

    数组(Array)应该是最基础的数据结构之一,它由相同类型的元素组成的集合,并按照一定的顺序存储在内存中。每个元素都有一个唯一的索引,可以用于访问该元素。 数组索引(Index): 数组中的每个元素都有一个唯一的整数索引,从0开始计数。索引用于访问数组中的元素

    2024年02月08日
    浏览(51)
  • JavaScript数据结构与算法整理------数组

            数组的标准定义: 一个存储元素的线性集合,元素可以通过索引来任意存取,索引通常是数字,用来计算元素之间存储位置的偏移量 ,几乎所有的编程语言都有类似的数据结构,而JavaScript的数组略有不同。         JavaScript中的数组是一种特殊的对象,用来表示偏

    2023年04月24日
    浏览(62)
  • 【数据结构和算法】寻找数组的中心下标

    Java基础合集 数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 前缀和的解题模板 2.1.1 最长递增子序列长度 2.1.2 寻找数组中第 k 大的元素 2.1.3 最长公共子序列长度 2.1.4 寻找数组中第 k 小的元素 2

    2024年02月04日
    浏览(53)
  • 数据结构与算法-数组(附阿里面试题)

            给你一个文件里面包含全国人民(14亿)的年龄数据(0~180),现在要你统计每一个年龄   有多少人?          给定机器为 单台+2CPU+2G内存。不得使用现成的容器,比如map等。 (这一句可以忽略)         在以上情况下你该如何以最高效的方法来解决这个

    2024年02月13日
    浏览(36)
  • 【数据结构和算法】使用数组的结构实现链表(单向或双向)

    上文我们通过结构体的结构实现了队列 、以及循环队列的实现,我们或许在其他老师的教学中,只学到了用结构体的形式来实现链表、队列、栈等数据结构,本文我想告诉你的是,我们 可以使用数组的结构实现链表、单调栈、单调队列 目录 前言 一、用数组结构的好处 1.数

    2024年01月20日
    浏览(74)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包