8

我试图解决这个问题。

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

一对整数 (P, Q),使得 0 ≤ P ≤ Q < N,称为数组 A 的切片。切片由元素 A[P]、A[P + 1]、...、一个[问]。不同的切片是仅由唯一数字组成的切片。也就是说,单个数字在切片中出现的次数不超过一次。

例如,考虑整数 M = 6 和数组 A 使得:

A[0] = 3
A[1] = 4
A[2] = 5
A[3] = 5
A[4] = 2 

正好有九个不同的切片:(0, 0), (0, 1), (0, 2), (1, 1), (1,2), (2, 2), (3, 3), ( 3, 4) 和 (4, 4)。

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

提前致谢。

#include <algorithm>
#include <cstring>
#include <cmath>
#define MAX 100002

// you can write to stdout for debugging purposes, e.g.
// cout << "this is a debug message" << endl;

using namespace std;

bool check[MAX];

int solution(int M, vector<int> &A) {
    memset(check, false, sizeof(check));
    int base = 0;
    int fibot = 0;
    int sum = 0;

    while(fibot < A.size()){

        if(check[A[fibot]]){
            base = fibot;
        }

        check[A[fibot]] = true;

   sum += fibot - base + 1;
        fibot += 1;  
    }

    return min(sum, 1000000000);
}
4

5 回答 5

3

解决方案不正确,因为您的算法错误。

首先,让我向您展示一个反例。让A = {2, 1, 2}. 第一次迭代:base = 0, fibot = 0,sum += 1.没错。第二个:base = 0, fibot = 1, sum += 2. 这也是正确的。最后一步:fibot = 2check[A[fibot]] is true,因此,base = 2。但它应该是1。因此,您的代码1 + 2 + 1 = 4在正确答案时返回1 + 2 + 2 = 5

正确的做法可能是这样的:从L = 0. 对于每个Rfrom0n - 1,继续L向右移动 ,直到子数组仅包含不同的值(您可以维护数组中每个值的出现次数,并使用A[R]可以多次出现的唯一元素这一事实)。

您的代码还有一个问题:如果测试平台上的变量是 32 位类型,则sum变量可能会溢出int(例如,如果 的所有元素A都是不同的)。

至于为什么你的算法不正确的问题,我不知道为什么它首先应该是正确的。你能证明这个吗?这个base = fibot任务对我来说看起来很随意。

于 2016-11-28T17:37:27.923 回答
0

感谢https://www.martinkysel.com/codility-countdistinctslices-solution/帮助我的 100% python 解决方案

def solution(M, A):
    
        the_sum = 0
    
        front = back = 0
    
        seen = [False] * (M+1)
    
        while (front < len(A) and back < len(A)):
    
            while (front < len(A) and seen[A[front]] != True):
    
                the_sum += (front-back+1)
    
                seen[A[front]] = True
    
                front += 1
    
            else:
    
                while front < len(A) and back < len(A) and A[back] != A[front]:
    
                    seen[A[back]] = False
    
                    back += 1
    
                seen[A[back]] = False
    
                back += 1
                   
        return min(the_sum, 1000000000)  
           
于 2021-04-08T13:32:13.303 回答
0

我想分享我在 C++ 中实现的算法的解释,然后是实际实现。

  1. 请注意,不同切片的最小数量是 N,因为每个元素都是一个不同的单项切片。
  2. 从第一个元素开始后退索引。
  3. 从第一个元素开始前索引。
  4. 向前推进,直到我们在序列中找到重复项。
  5. 在每次迭代中,将计数器增加必要的数量,这是前后的差异。
  6. 如果我们在任何迭代中达到最大计数,只需立即返回以进行轻微优化。
  7. 在序列的每次迭代中,记录已经发生的元素。
  8. 一旦我们找到一个副本,将后面的索引推进到副本之前。
  9. 当我们推进后面的索引时,清除所有出现的元素,因为我们在这些元素之外开始一个新的切片。

该解决方案的运行时复杂性在于O(N)我们遍历每个
元素。

这个解决方案的空间复杂度是O(M)因为我们有一个哈希来存储序列中出现的元素。这个哈希的最大元素是 M。

int solution(int M, vector<int> &A)                                             
{                                                                               
  int N = A.size();                                                             
  int distinct_slices = N;                                                      
  vector<bool> seq_hash(M + 1, false);                                          
  for (int back = 0, front = 0; front < N; ++back) {                            
    while (front < N and !seq_hash[A[front]]) { distinct_slices += front - back; if (distinct_slices > 1000000000) return 1000000000; seq_hash[A[front++]] = true; }
    while (front < N and back < N and A[back] != A[front]) seq_hash[A[back++]] = false;
    seq_hash[A[back]] = false;                                                  
  }                                                                             
                                                                                
  return distinct_slices;                                                       
}
于 2021-11-12T21:40:34.247 回答
-2

100% 使用 Ruby 的解决方案

LIMIT = 1_000_000_000

def solution(_m, a)
  a.each_with_index.inject([0, {}]) do |(result, slice), (back, i)|
    return LIMIT if result >= LIMIT
    slice[back] = true
    a[(i + slice.size)..-1].each do |front|
      break if slice[front]
      slice[front] = true
    end
    slice.delete back
    [result + slice.size, slice]
  end.first + a.size
end
于 2019-06-05T23:55:34.610 回答
-2

使用 Caterpillar 算法和S(n+1) = S(n) + n + 1where S(n)is count of slices for n-element array java 解决方案的公式可以是:

 public int solution(int top, int[] numbers) {
        int len = numbers.length;
        long count = 0;

        if (len == 1) return 1;

        int front = 0;
        int[] counter = new int[top + 1];

        for (int i = 0; i < len; i++) {
            while(front < len && counter[numbers[front]] == 0 ) {
                count += front - i + 1;
                counter[numbers[front++]] = 1;
            }

            while(front < len && numbers[i] != numbers[front] && i < front) {
                counter[numbers[i++]] = 0;
            }

            counter[numbers[i]] = 0;

            if (count > 1_000_000_000) {
                return 1_000_000_000;
            }
        }

        return count;
    }
于 2019-10-12T16:15:13.830 回答