【问题标题】:Count the number of distinct slices (containing only unique numbers)计算不同切片的数量(仅包含唯一数字)
【发布时间】:2020-01-05 16:07:24
【问题描述】:

我解决了提供的以下 Codilty 问题。

一个整数 M 和一个由 N 个非负数组成的非空数组 A 给出整数。数组 A 中的所有整数都小于或等于 M.

一对整数 (P, Q),使得 0 ≤ P ≤ Q

例如,考虑整数 M = 6 和数组 A,这样:

A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 There are exactly nine distinct slices: (0, 0), (0, 1), (0, 2), (1, 1), (1, 2), (2, 2), (3, 3), (3, 4) and (4, 4).

目标是计算不同切片的数量。

写一个函数:

类解决方案 { public int solution(int M, int[] A); }

给定一个整数 M 和一个由 N 组成的非空数组 A 整数,返回不同切片的数量。

如果不同切片的数量大于 1,000,000,000,则 函数应该返回 1,000,000,000。

例如,给定整数 M = 6 和数组 A,这样:

A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 the function should return 9, as explained above.

为以下假设编写一个有效的算法:

N 是 [1..100,000] 范围内的整数; M是一个整数 范围 [0..100,000];数组 A 的每个元素都是一个整数 范围 [0..M]。

我的解决方案在这里,

public static int solution(int M, int[] A) {

        boolean[] visited = new boolean[M + 1];

        int N = A.length;


        int result = 0;

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

            int k = i;
            int count = 0;

            while (i < N && !visited[A[i]]) {

                count++;
                visited[A[i]] = true;

                i++;
            }

            i -=1;

            // 3, 4, 5, 5, 2, 5, 4
            int j = i;

            while (j >= k && visited[A[j]]) {

                visited[A[j]] = false;
                j--;
            }

            result += count * (count + 1) / 2;
        }

        return result;
    }

但是,在线评委估计的正确性和性能较低。我该如何改进?

【问题讨论】:

    标签: java arrays algorithm


    【解决方案1】:

    似乎您选择了正确的方法,但在实现细节上犯了错误 - 在坏主意中减少索引。

    制作两个索引 - 左和右。

    a) 向右移动直到遇到重复的元素(“stopper”)——本质上你是在第一个 while 循环中执行这一步。如果你在停止前做了 n 步 - 有 n*(n-1)/2 个切片。

    b) 现在向左移动索引,直到找到与“stopper”相同的元素并在其后停止。当前切片又好了

    重复 a) 和 b) 直到结束。请注意,两个索引都只向前移动,复杂度是线性的

    【讨论】:

      【解决方案2】:

      我喜欢 MBo 澄清的两个指针方法和 O(1) 更新访问数组的想法。这是一个单指针的想法,它使用哈希集来实现唯一性,每次新段开始时都会清除它。

      function f(A){
        var sum = 0
        var set = new Set
        var len = 0
        
        for (a of A){
          if (sum >= 1000000000)
            return 1000000000
            
          if (set.has(a)){
            sum += len*(len+1)/2
            len = 1
            set.clear()
            
          } else {
            len++
            set.add(a)
          }
        }
        sum += len*(len+1)/2
        
        return Math.min(sum, 1000000000)
      }
      
      var A = [3, 4, 5, 5 ,2]
      
      console.log(f(A))

      【讨论】:

      • 好吧,我相信我错过了指令If the number of distinct slices is greater than 1,000,000,000, the function should return 1,000,000,000.
      猜你喜欢
      • 2017-04-12
      • 2021-09-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 2022-01-14
      • 2020-02-03
      • 1970-01-01
      • 2012-07-19
      相关资源
      最近更新 更多