计算数组

时间:2016-11-28 15:22:48

标签: c++ algorithm vector problem-steps-recorder

我试图解决this问题。

  

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

     

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

     

例如,考虑整数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 个答案:

答案 0 :(得分:2)

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

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

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

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

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

答案 1 :(得分:0)

使用Ruby的100%解决方案

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

答案 2 :(得分:0)

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

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)  
           

答案 3 :(得分:-1)

使用Caterpillar算法和S(n+1) = S(n) + n + 1其中S(n)n元素数组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;
    }