每日一练2024.5.9

题目:

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

此时,你需要选定一个数字 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
解释:没有满足要求的分组。

解题:

        这是一道典型的编程问题,通常出现在算法和数据结构相关的挑战中。其核心要求是寻找一组数X,使得给定数组(牌堆 deck)能够按照一定的规则分组。这里的规则是:每组牌的数量需要相同,且每组牌上的数字也需要相同。

解题思路可以分为以下几步:

  1. 计数:首先需要统计deck中每个数字出现的频率。例如,如果deck[1,2,3,4,4,3,2,1],那么数字1出现2次,数字2出现2次,数字3出现2次,数字4出现2次。

  2. 寻找最大公约数:在得到每个数字的出现次数后,需要寻找这些次数的最大公约数(GCD)。如果最大公约数大于等于2,那么意味着可以将牌分组,每组牌的数目都是这个最大公约数,且每组中的牌的数字相同。

  3. 判断结果:最终的判断基于最大公约数是否大于等于2。如果是,返回true(表示可以分组),否则返回false(表示无法满足题目中的分组要求)。

        举例来说,在示例1中,每种数字出现的次数都是2,它们的最大公约数也是2,因此可以分为每组2张牌的几组,每组内的数字相同,所以返回true

        在示例2中,数字1, 2, 3的出现次数各为3,它们的最大公约数是1,因为题目要求X至少为2,所以这个情况下没有满足要求的分组方法,返回false。        

代码:

import java.util.HashMap;
import java.util.Map;
// Solution类,包含实现算法的方法
class Solution {
    // hasGroupsSizeX,这是核心的公共方法,它检查能否将deck分成满足条件的组。
    // 它接受一个整型数组作为参数。
    public boolean hasGroupsSizeX(int[] deck) {
        // 频率数组count,用来统计deck中每个数字出现的次数。
        // 我们这里假设deck中的数值不会超过10000。
        int[] count = new int[10000];
        for (int num : deck) {
            count[num]++;
        }

        // g用来记录当前找到的所有数的次数的最大公约数。
        int g = -1;
        for (int i = 0; i < count.length; i++) {
            if (count[i] > 0) {
                // 初始化g或者不断找到新的g(新的数的次数和当前g的最大公约数)。
                if (g == -1) {
                    g = count[i];
                } else {
                    g = gcd(g, count[i]);
                }
                // 如果在任何时候g变为1,由于问题的设定,直接返回false。
                if (g == 1) {
                    return false;
                }
            }
        }
        // 如果g不小于2,则说明我们可以将deck按要求分组。
        return g >= 2;
    }

    // 辅助方法gcd,它利用循环计算两个正整数的最大公约数。
    private int gcd(int a, int b) {
        while (b != 0) {
            int t = b;      // 在这里,t是用来暂存b的值。
            b = a % b;      // 根据欧几里得算法更新b的值为a除以b的余数。
            a = t;          // 然后将a的值设置为之前b的值。
        }
        return a;           // 在b变成0时,最大公约数就是a。
    }
}

知识点概览:

  1. Java基础 - 方法的定义、循环、条件语句、返回值。
  2. 数组 - 使用静态分配的数组来存储整型数据。
  3. 增强型for循环 (for-each loop) - 遍历数组中的元素。
  4. 辅助方法(gcd方法) - 封装逻辑以与主要逻辑分离,并实现代码复用。
  5. 算法 - 最大公约数的计算(欧几里得算法)。
  6. 变量的作用域和生命周期 - g变量、临时变量it在方法内的局部使用。
  7. 逻辑短路 - 在发现gcd为1的情况下立即返回false,不需要执行更多的操作。
  • 数组int[] count = new int[10000],这一句初始化了一个大小为10000的整型数组。这个数组被用来统计每个数字出现的次数。我们可以使用数组而不是HashMap因为整数可以直接映射到数组索引,这里我们假设deck中的整数不会超过10000。

  • 增强型for循环for (int num : deck)这个循环是Java的增强型for循环,它能够遍历数组或者任何实现了Iterable接口的集合中的所有元素。

  • 循环与条件判断for (int i = 0; i < count.length; i++)这个循环遍历我们之前创建的count数组。if (count[i] > 0)这个判断确保我们只在数的出现次数不为0时进行gcd计算。

  • 最大公约数计算函数(gcd函数):这是一个本地辅助方法,它通过循环计算两个数的最大公约数,而不是递归,这可以提高效率并避免栈溢出错误。该方法是一个封装的逻辑块,可以从主逻辑中分离出来,并在需要时被重用。

  • 逻辑短路:在计算gcd的过程中,代码通过判断if (g == 1)来检查是否已经有证据表明无法按要求进行分组。如果gcd是1,函数会立即返回false,因为根据数学定理,gcd为1说明没有其他的数大于1可以整除数组中的所有数的出现频率。

  • 变量作用域g是一个整型变量,它存储了当前gcd的值;t是gcd算法中的临时变量,用于交换数值。

知识点类别 描述
Java基础 方法定义、循环控制、条件语句、返回值等
数组 使用固定大小的数组来统计频次,整数作为数组索引
增强型for循环 遍历数组中的元素,简化集合或数组的迭代
辅助方法(GCD方法) 欧几里得算法的实现,局部逻辑封装,增强代码的复用性
算法 最大公约数(GCD)的求解,关键于问题的解决
变量作用域和生命周期 局部变量g用于存储最大公约数,it用于循环和值交换,在方法内部控制其生命周期
逻辑短路 提前返回逻辑,当算出的最大公约数为1时,立即决定输出,并结束方法的执行,提升代码的效率和执行速度

 

0502ffb80b674896ab1ea3389904a244.png2024.5.9

 

相关推荐

  1. 算法--每日

    2024-05-11 04:42:04       39 阅读
  2. 每日算法

    2024-05-11 04:42:04       26 阅读
  3. 【PMP】每日1

    2024-05-11 04:42:04       38 阅读
  4. 【PMP】每日2

    2024-05-11 04:42:04       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-11 04:42:04       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-11 04:42:04       72 阅读
  3. 在Django里面运行非项目文件

    2024-05-11 04:42:04       58 阅读
  4. Python语言-面向对象

    2024-05-11 04:42:04       69 阅读

热门阅读

  1. 【八股】消息中间件

    2024-05-11 04:42:04       26 阅读
  2. 笔记2024

    2024-05-11 04:42:04       25 阅读
  3. Python入门系列-03 matplotlib库安装

    2024-05-11 04:42:04       31 阅读
  4. Rancher简介

    2024-05-11 04:42:04       28 阅读
  5. Ansible

    Ansible

    2024-05-11 04:42:04      22 阅读
  6. php 修改 文件权限 函数chmod()

    2024-05-11 04:42:04       31 阅读