【问题标题】:find max students who can attend the session找到可以参加会议的最多学生
【发布时间】:2022-12-20 01:55:17
【问题描述】:

培训课程将在接下来的 10 天内进行两次。有 N 名员工(编号从 0 到 N-1)愿意参加。每个员工都提供了他们能够参加培训的未来 10 天的列表。员工偏好表示为字符串数组。 N[K] 是一个由数字 (0-9) 组成的字符串,表示第 k 名员工能够出席的天数。

需要找出在两个预定日期中的至少一天内可以参加的最大员工人数。

例如

Given E = ["039", "4", "14", "32", "", "34", "7"], the answer is 5. It can be achieved for example by running training on days 3 and 4. This way employees number 0, 1, 2, 3 and 5 will attend the training.
Given E = ["801234567", "180234567", "0", "189234567", "891234567", "98", "9"], the answer is 7. It can be achieved for example by running training on days 0 and 9. This way employees all will attend the training.
Given E = ["5421", "245", "1452", "0345", "53", "345"], the answer is 6. It can be achieved for example by running training once on day 5. This way employees all will attend the training.

这是我未能解决的测试。

我试过这个,但它只适用于 1,2 个案例。任何人都可以分享解决它的任何技巧吗?

public int solution(String[] E) {
        Map<String, Integer> daysCount = new HashMap<String, Integer>();
        int n = E.length;

        for (int i = 0; i < n; i++) {
            String inp = E[i];
            for (int j = 0; j < inp.length(); j++) {

                char c = inp.charAt(j);

                if (daysCount.containsKey(Character.toString(c))) {

                    daysCount.merge(Character.toString(c), 1, Integer::sum);

                }

                else {
                    daysCount.put(Character.toString(c), 1);
                }

            }

        }

        Map<String, Integer> topTen = daysCount.entrySet().stream()
                .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())).limit(2)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));

        List<String> vals = new ArrayList<String>();

        topTen.entrySet().forEach(entry -> {
            vals.add(entry.getKey());
        });

        int out = 0;
        StringBuilder sb = new StringBuilder();

        for (int z = 0; z < vals.size(); z++) {

            sb.append(vals.get(z));

        }

        for (int i = 0; i < n; i++) {

            String inp = E[i];

            if (inp.matches(".*[" + sb.toString() + "].*")) {

                out++;

            }

        }

        return out;
    }

更新

我已经实施的是,计算所有员工天数偏好中的所有天数,并在一天中进行最大计数,然后检查该天存在于多少员工天数偏好中。

【问题讨论】:

  • 你能放下你的算法?如果 A) 你实际上是什么,那会更容易看清通缉实施符合要求,并且 B) 您实施的与您想要实施的相匹配。
  • @Fildor,在我的问题中提到了更新
  • 采取一个简单的失败案例并开始调试。
  • @MrSmith42,但我认为我的方法是错误的。也许任何人都可以建议解决这个问题
  • 这看起来可以通过动态规划进行优化。

标签: java arrays algorithm


【解决方案1】:

诀窍是确定两个不同的集合,这两个集合可以使员工数量最大化。
您的代码中的问题是,您只比较最多员工首选的两组(天)。这就是为什么在情况 2 中,您的代码仅比较单对(第 8 天和第 9 天),这给出了具有 6 名员工的不同集合,而最大不同集合是通过比较第 0 天和第 9 天(即 7 名员工)给出的。
因此,您应该比较所有日期的所有集合而不取 max 2(这将删除所有 HashMap 和 max 逻辑)。
这是代码,可能没有优化但可以工作

public int solution(String[] E) {
        int n = E.length;
        int max = 0;

        for(int i=0;i <10; i++)
            for(int j=i+1;j<10; j++) {
                //create all pairs of days one by one like 01, 02, 03, 04, 05..... 89
                String sb = i+""+j;
                int out = 0;                
                for (int k = 0; k < n; k++) {

                    String inp = E[k];
                        
                    if (inp.matches(".*[" + sb.toString() + "].*")) {
                        out++;
                    }

                }
                if(out>max) {
                    max=out;
                }
            }

        return max;
    }

对于其他不理解这一点的人,您可以使用 2D 矩阵来完成。

days    0   1   2   3   4   5   6   7   8   9
emp0    1   1   1   1   1   1   1   1   1   0
emp1    1   1   1   1   1   1   1   1   1   0
emp2    1   0   0   0   0   0   0   0   0   0
emp3    0   1   1   1   1   1   1   1   1   1
emp4    0   1   1   1   1   1   1   1   1   1
emp5    0   0   0   0   0   0   0   0   1   1
emp6    0   0   0   0   0   0   0   0   0   1

将所有组/天相互进行 OR,然后将所有 OR 结果相加。 例如在上面的示例中,第 8 列和第 9 列将给出最大不同集,即 7

【讨论】:

    【解决方案2】:

    我认为您实施的问题在于忽略了这样一个事实,即第一次计数后出勤率第二高的那一天不一定是要选择的第二天。

    例如,在E = ["01", "01", "2"] 的情况下,乍一看,01 似乎是所选日期的合适人选。但是,由于01 都是由同一个人选择的,因此选择2 作为所选日期之一实际上会使服务员的数量最大化:

    E = ["01", "01", "2"]
    
    Chosen days [0,1]          -> Total num of attendants is 2
    Chosen days [0,2] or [1,2] -> Total num of attendants is 3
    

    因此,我认为您必须在不考虑已经获得席位的员工的偏好的情况下计算第二受欢迎的出勤率。

    【讨论】:

      【解决方案3】:
      public int solution(String[] e) {
              // Create a set to store the days that each employee is available
              Set<Integer>[] employeeAvailability = new Set[e.length];
              for (int i = 0; i < e.length; i++) {
                  employeeAvailability[i] = new HashSet<>();
                  for (int j = 0; j < e[i].length(); j++) {
                      employeeAvailability[i].add(Character.getNumericValue(e[i].charAt(j)));
                  }
              }
      
              // Check how many employees are available on each day
              int[] availabilityCount = new int[10];
              for (int i = 0; i < 10; i++) {
                  for (int j = 0; j < e.length; j++) {
                      if (employeeAvailability[j].contains(i)) {
                          availabilityCount[i]++;
                      }
                  }
              }
      
              // Sort the availability count in descending order
              Arrays.sort(availabilityCount);
      
              // Return the maximum number of employees available on at least one of the two scheduled days
              return Math.max(availabilityCount[9], availabilityCount[8]);
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-02
        • 2020-03-27
        相关资源
        最近更新 更多