Codility PermCheck为什么我的解决方案不起作用

时间:2014-12-15 22:19:39

标签: arrays algorithm

我正在努力解决编码练习的Codility课程,PermCheck就是其中之一。

[编辑] 问题描述:

给出了由N个整数组成的非空零索引数组A. 置换是包含从1到N的每个元素一次且仅一次的序列。 例如,数组A使得:

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

是一个排列,但是数组A使得:

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

不是排列,因为缺少值2。 目标是检查阵列A是否是排列。 写一个函数: class Solution {public int solution(int [] A); } 如果给定零索引数组A,则如果数组A是排列则返回1,如果不是则返回0。 例如,给定数组A使得:

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

该函数应返回1。 给定数组A:

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

该函数应返回0。 假使,假设: N是[1..100,000]范围内的整数; 数组A的每个元素都是[1..1,000,000,000]范围内的整数。

我现在的解决方案是:

class Solution {
    public int solution(int[] A) {

        final int N = A.length;
        long sum = N * (N+1)/2;

        for(int i=0; i<A.length; i++) {
            sum -= A[i];
        }

        return sum == 0 ? 1 : 0;
    }
}

并且results不是我所期待的。我知道有很多解决方案,但我想知道解决方案的问题是什么。我错过了什么角落的案例。结果页面不显示上述解决方案失败的输入列表。

38 个答案:

答案 0 :(得分:3)

这不起作用的原因是排列(如所解释的)不是达到特定总和的唯一方法,正如您的解决方案所假设的那样。例如:

[0, 1, 2, 3] // Sum == 6
[0, 2, 2, 2] // Sum == 6

根据所写的问题描述,我不认为这意味着给定的数据没有重复。

答案 1 :(得分:3)

代码:08:25:58 UTC,c,final,得分:100.00

   int solution(int A[], int N) {
    // write your code in C99

    int T[N];
//when the compiler sees N variable declaration it cannot know how many         
//elements there are in the array.
//must manually initialize that array.
    memset( T, 0, N*sizeof(int) ); 
    for (int i=0;i<N;i++)
    {
    if (A[i]>N)
        {
        return 0;
        }
    T[A[i]-1]++;
    }
    int sum=0;
   for (int i=0;i<N;i++)
    {
    sum =sum+T[A[i]-1];
    }
    return (sum==N)?1:0;
}

答案 2 :(得分:2)

如果N是100,000,则N *(N + 1)/ 2表达式导致整数溢出(尽管sum是long,N是int)。不确定是否还有其他错误。

答案 3 :(得分:2)

您可以将它们添加到集合中并在末尾检查长度。如果列表中的任何值大于列表大小,您都可以提早使用它,因为它永远不会成为有效的烫发。

https://app.codility.com/demo/results/training47WAU6-G8F/

import java.util.*;

class Solution {
    public int solution(int[] A)
    {
        Set<Integer> all = new HashSet<Integer>();
        
        for( int v : A )
        {
            if( v > A.length ) return 0;
            all.add(v);
        }
        
        return all.size() == A.length ? 1:0;
    }
}

答案 4 :(得分:1)

我的解决方案在python中,希望这会有所帮助。

 def solution(A):
    # write your code in Python 3.6
    N = len(A)
    sum1 =sum(range(1, N+1))
    sum2 = sum(A)
    if len(set(A)) != len(A):
        return 0
    if (sum1 - sum2) != 0:
        return 0
    return 1 

答案 5 :(得分:1)

这是Python中的一个简单代码:

def solution(A):
    # write your code in Python 3.6
    N = len(A)
    occurance = {}
    A.sort()
    if A[-1] == N:
        for item in A:
            if item <= 0:
                return 0
            elif item not in occurance:
                occurance[item] = True
            else:
                return 0
        return 1
    else:
        return 0

答案 6 :(得分:1)

这是我的分数为100%的解决方案。不需要额外的空间,而且,它使时间复杂度为O(n)。它通过将相应索引处的元素设置为负来标记当前访问的元素。例如1可以在数组中的任何位置,但是如果第0个索引的元素为负,则表示已访问1。

function solution(A) {
    for(let i=0 ;i< A.length;  i++){
        const elementIndex = Math.abs(A[i]) - 1;
        if(elementIndex < A.length){
           A[elementIndex] = -A[elementIndex];
        }
    }

    for(let i=0 ;i< A.length;  i++){
        if(A[i] > 0) {
            return 0;
        }
    }

    return 1;
}

答案 7 :(得分:1)

C ++得分:100。

我们的想法是制作一个新的数组B包含N+1元素和所有false,然后设置B[A[i]] = true。如果我们发现任何BB[i],则会false进行迭代,然后返回0,否则1

复杂度为O(2N)〜= O(N)。

#include <vector>

using namespace std;

int solution(vector<int> &A) {
    int n = A.size();

    vector<bool> v;
    v.resize(n + 1);

    for (int i = 0; i < n; i++) {
        int element = A[i];
        if (element > n) {
            return 0;
        }
        if (v[element]) {
            return 0;
        }
        v[element] = true;
    }
    for (int i = 1; i < v.size(); i++) {
        if (!v[i]) {
            return 0;
        }
    }
    return 1;
}

答案 8 :(得分:1)

以下是java 100%in codility中的解决方案。

public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {

    private List<todo> todoList;

    public class ViewHolder extends RecyclerView.ViewHolder {
        public TextView toDoTextView;

        public ViewHolder(View itemView) {
            super(itemView);

            toDoTextView = (TextView) itemView.findViewById(R.id.to_do);
        }
    }

    public ItemAdapter(List<todo> todoList) {
        this.todoList = todoList;
    }

    @Override
    public ItemAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(ItemAdapter.ViewHolder holder, int position) {
        todo toDo = todoList.get(position);
        holder.toDoTextView.setText(toDo.getToDo());
    }


    @Override
    public int getItemCount() {
        return todoList.size();
    }
}

答案 9 :(得分:1)

如果存在重复 - 返回0 我已经实现了100%传递

https://codility.com/demo/results/trainingWX2E92-ASF/

public static int permCheck(int A[]){

    Set<Integer> bucket = new HashSet<Integer>();
    int max = 0;
    int sum=0;
    for(int counter=0; counter<A.length; counter++){
        if(max<A[counter]) max=A[counter];
        if(bucket.add(A[counter])){
            sum=sum+A[counter];
        }
        else{
            return 0;
        }
    }
    System.out.println(max+"->"+sum);
    int expectedSum = (max*(max+1))/2;
    if(expectedSum==sum)return 1;

    return 0;
}

答案 10 :(得分:1)

具有100%传递结果的JavaScript解决方案:

function solution(A) {
    A.sort(function(a,b){
       return a - b; 
    });
    var count = 0;
    for(i = 0; i < A.length; i++){
        if(A[i] === i+1){
            count++;
        } else {
            break;
        }
     } 
    if(count === A.length){
     return 1;   
    }
    else {
     return 0;   
    } 
}

答案 11 :(得分:0)

这是我的解决方法

UNIT_PIXEL=0
UNIT_INCH=1 
UNIT_MM=2
UNIT_POINT=3
UNIT_PICA=4

function solution(A) { const t = A.reduce((acc, cur, index) => acc ^ cur ^ (index + 1), 0) return A.reduce((acc, cur, index) => acc ^ cur ^ (index + 1), 0) === 0 ? 1 : 0 } 很棒。

答案 12 :(得分:0)

Java 100:

    Arrays.sort(A);
    if (A[0] != 1 || A[A.length - 1] != A.length)
        return 0;

    HashSet<Integer> set = new HashSet<Integer>();
    for (int i = 0 ; i < A.length; i++){
        set.add(A[i]);
    }

    if (set.size() != A.length)
        return 0;

    return 1;

答案 13 :(得分:0)

C# 100% 解决方案

using System;

class Solution {
    public int solution(int[] A) {
        // write your code in C# 6.0 with .NET 4.5 (Mono)
        bool[] boolArray = new bool[A.Length];

        foreach(var v in A)
        {
            try
            {
                boolArray[v-1] = true;
            }
            catch
            {
                return 0;
            }
        }
           
        foreach (var v in boolArray)
        {
            if(v==false)
                return 0;
        } 

        return 1;
    }
}

答案 14 :(得分:0)

我使用Java的答案更加简单易懂100%,希望这会有所帮助:

public static int solution(int [] A){
       
  Arrays.sort( A );
  int index = 1;

  for ( int i = 0 ; i < A.length ; i++ )
  { 
    if ( A [ i ] ! = index)
    {
      return 0;
    }
    index++;
  }
  return 1;
}

答案 15 :(得分:0)

public func solution(_ A : inout [Int]) -> Int {
// write your code in Swift 4.2.1 (Linux)
 if A.count == 0 {
    return 0
}

var arr = A.sorted(by : {$0 < $1})
if arr[0] != 1{
    return 0
}

for i in 0..<arr.count - 1{
    
    if arr[i] + 1 != arr[i + 1]{
        return 0
    }
}

return 1
} 

答案 16 :(得分:0)

在Python中:

def solution(A):
    new_list = [i for i in range(min(A), max(A), 1)]
    if len(set(new_list) - set(A)) > 0: return 0
    else: return 1
    
    pass

答案 17 :(得分:0)

我的可读性解决方案基于简单的数学(集合差异)来检查排列:

import java.util.HashSet;
import java.util.Set;

class Solution {
    public int solution(int[] A) {
        return isPermutation(A) ? 1 : 0;
    }

    private boolean isPermutation(int[] A) {
        Set<Integer> set1 = new HashSet<>();
        Set<Integer> set2 = new HashSet<>();
        for (int i = 0; i < A.length; i++) {
            set1.add(A[i]);
            set2.add(i + 1);
        }
        set2.removeAll(set1);
        return set2.isEmpty();
    }
}

total score 100% and the detected time complexity: O(N) or O(N * log(N))

答案 18 :(得分:0)

使用C#的两个衬板100%解决方案

public int solution(int[] A) {
    // write your code in C# 6.0 with .NET 4.5 (Mono)
    var A2 = Enumerable.Range(1, A.Length);
        return A2.Except(A).Count() == 0 ? 1 : 0;
}

答案 19 :(得分:0)

js解决方案(100/100-O(N))

function solution(A) {
  for (let i = 0; i < A.length; i++)
    if (A[i] > A.length) return 0;
  return new Set(A).size === A.length ? 1 : 0;
};

答案 20 :(得分:0)

使用List的另一种方法:

public int solution(int[] A) {
        // write your code in C# 6.0 with .NET 4.5 (Mono)
          List<double> sum = A.ToList().Select(x => (double)x).ToList();
            double maxElem = A.ToList().Max();
            double res = (maxElem * (maxElem + 1)) / 2;
            if (sum.Sum() == res && sum.Distinct().Count() == maxElem)
            {
                return 1;
            }
            else
            {
                return 0;
            }
    }

答案 21 :(得分:0)

纯Java给了我100%:

public int solution(int[] A) {
    int check[] = new int[A.length];
    int max = 0;
    int total = 0;
    for (int i = 0; i < A.length; i++) {
        total += A[i];
        max += i + 1;
        if (A[i] > A.length || check[A[i]-1] > 0)
            return 0;
        else
            check[A[i]-1] = A[i];
    }
    return max == total ? 1 : 0;
}

答案 22 :(得分:0)

功能性的Scala解决方案也获得了100%的收益。希望这会帮助某人。

Person

答案 23 :(得分:0)

Python中具有O(N)复杂度的XOR解决方案,它基于X ^ X = 00 ^ X = x

的思想
def solution(A):
    # write your code in Python 3.6
    chk = 0
    l = len(A)

    for i,x in enumerate(A):
        if x < 1 or x > l:
            return 0
        else:
            chk = chk ^ i+1 ^ x
    if chk != 0:
        return 0
    else:
        return 1 

答案 24 :(得分:0)

我现在已经发布了这个解决方案,它给出了100%。也许这有助于获得任何想法......

    /**
     * Storage complexity O(N/64). That does mean that for 1000 elements array will be reserved
     *  only 16 additional long values.
     * Time complexity the same - O(N)
     * @author Egor
     *
     */
    public class SolutionBitFlags {

        private static final int ARRAY_SIZE_LOWER = 1;
        private static final int ARRAY_SIZE_UPPER = 1000000;
        private static final int NUMBER_LOWER = 1;
        private static final int NUMBER_UPPER = 1000000000;

        public static class Set {

            final long[] buckets;

            public Set(int size) {
                this.buckets = new long[(size % 64 == 0 ? (size/64) : (size/64) + 1)];
            }

            /**
             * number should be greater than zero
             * @param number
             */
            public void put(int number) {
                buckets[getBucketindex(number)] |= getFlag(number); 
            }

            public boolean contains(int number) {
                long flag = getFlag(number);
                // check if flag is stored
                return (buckets[getBucketindex(number)] & flag) == flag;
            }

            private int getBucketindex(int number) {
                if (number <= 64) {
                    return 0;
                } else if (number <= 128) {
                    return 1;
                } else if (number <= 192) {
                    return 2;
                } else if (number <= 256) {
                    return 3;
                } else if (number <= 320) {
                    return 4;
                } else if (number <= 384) {
                    return 5;
                } else 
                    return (number % 64 == 0 ? (number/64) : (number/64) + 1) - 1;
            }

            private long getFlag(int number) {
                if (number <= 64) {
                    return 1L << number;
                } else
                    return 1L << (number % 64);
            }
        }

        public static int solution(final int[] A) {
            if (A.length < ARRAY_SIZE_LOWER || A.length > ARRAY_SIZE_UPPER) {
                throw new RuntimeException("Array size out of bounds");
            }
            switch (A.length) {
            case 1:
                return (A[0] == 1 ? 1 : 0);
            case 2:
                return ((A[0] == 1 && A[1] == 2) || (A[0] == 2 && A[1] == 1) ? 1 : 0);
            default:
                {
                    // we have to check 2 conditions:
                    // - number is not out of range [1..N], where N - array size
                    // - number is unique
                    // if either of them fails - array is not permutation
                    int ai;
                    Set set = new Set(A.length);
                    for (int i = 0; i < A.length; i++) {
                        if ((ai = A[i]) < NUMBER_LOWER || ai > NUMBER_UPPER) {
                             throw new RuntimeException("Number out of bounds");
                        }
                        // check boundaries
                        if (ai > A.length) {
                            return 0;
                        } else {
                             // check if already present in set (if present - return 0)
                            if (set.contains(ai)) {
                                return 0;
                            } else {
                                // put to set (if not in set )
                                set.put(ai);
                            }
                        }
                    }
                }
                break;
            }
            return 1;
        }
    }

答案 25 :(得分:0)

我的JavaScript解决方案获得了100个全面支持。基本上,我会遍历数组一次,并使每个值成为新数组中索引的值,并将其值设置为true(或wtv,只要它是真实的)。这样做时,我检查是否已将任何值输入到新数组中。然后,我遍历数组,如果有任何错误,则立即返回0。我想足够接近O(2n)。

const permCheck = (A) => {
    orderedArr = [];
    for (let i = 0; i < A.length; i++) {
        if (orderedArr[A[i]]) { return 0; } // duplicate - we out
        orderedArr[A[i]] = true;
    }
    for (let i = 1; i < orderedArr.length; i++) {
        if (!orderedArr[i]) {
            return 0;
        }
    }
    return 1;
}

答案 26 :(得分:0)

在Swift 4中,100%:

public func solution(_ A : inout [Int]) -> Int {
    if A.isEmpty {
        return 0
    }

    if A.count == 1 {
        return A[0] == 1 ? 1 : 0
    }

    for (index, elem) in A.sorted().enumerated() {
        if index + 1 != elem {
            return 0
        }
    }

    return 1
}

答案 27 :(得分:0)

PHP解决方案,在三个字段中占100%:

function solution($A) {

    $size = count($A); // SIZE OF ARRAY
    $sum = array_sum($A); // SUM OF ALL ELEMENTS

    $B = array(); // WE CHECK FOR ARRAYS WITH REPEATED VALUES 
    foreach($A as $key=>$val) {    
        $B[$val] = true; 
    } 
    $B= array_keys($res2); // A FOREACH AND ARRAY_KEYS IS 30x TIMES FASTER THAN ARRAY_UNIQUE 

    if($size != count($res2)) return 0; //IF THE SIZE IS NOT THE SAME THERE ARE REPEATED VALUES

    $total = ( $size * ( $size + 1) ) / 2; // WE CHECK FOR THE SUM OF ALL THE INTEGERS BETWEEN OUR RANGE
    return $sum == $total ? 1 : 0; // IF SUM OF ARRAY AND TOTAL IS EQUAL IT IS A PERMUTATION IF NOT THERE ARE SOME NUMBERS MISSING BUT NONE ARE REPEATED
}

答案 28 :(得分:0)

这是我在java中的解决方案:

/**
 * https://codility.com/demo/results/training4YUHYS-HDW/ 100%
 * 
 * Facts:
 * 1) A permutation is a sequence containing each element from 1 to N once, and only once.
 * 2) A non-empty zero-indexed array A consisting of N integers is given
 * 3) N is an integer within the range [1..100,000];
 * 4) each element of array A is an integer within the range [1..1,000,000,000].
 * 
 * Invariant: the sequence is in the range A[0] to A[N-1]
 * 
 * @param A
 * @return
 */
public static int solution(int[] A) {
    int result=1;
    int[] count = new int[A.length+1];
    for(int i=0; i<A.length; i++) {
        if(A[i]>A.length) return 0;
        if(count[A[i]]>0) return 0;
        count[A[i]]++;
    }
    for(int i=1; i<count.length; i++) {
        if(count[i]==0) {
            result =0;
            break;
        }
    }
    return result;
}

时间复杂度为O(2n),其等于O(n)。 https://codility.com/demo/results/training4YUHYS-HDW/

答案 29 :(得分:0)

据我所知,由于本课程需要O(n),所以解决方案应该没有排序。关于置换的关键字是序列,1到N只有一次。所以解决方案应该按顺序检查重复和所有元素。

public static int solution(int[] A)
    {
        if (A.Length == 1) return 1;

        var max = 0;

        var dic = new Dictionary<int, int>();

        //find duplicate
        for (var i = 0; i < A.Length; i++)
        {
            if (A[i] > max) max = A[i];

            if (!dic.ContainsKey(A[i]))
            {
                dic.Add(A[i], 1);
                continue;
            }

            dic[A[i]]++;
            if (dic[A[i]] > 1) return 0;
        }

        //check in sequence
        for (var i = 1; i <= max; i++)
        {
            if (!dic.ContainsKey(i))
            {
                return 0;
            }
        }

        return 1;
    }

但是,此代码无法使用extreme_min_max和单次测试,不知道为什么代码检查数组A的长度是否为1,只返回1.

答案 30 :(得分:0)

我认为因为它是计数元素章节所需的解决方案应该使用元素计数,然后检查桶数组中是否有一个元素。我的Swift解决方案是这样的。但没有检查Codility:

public func PermCheck(_ A : inout [Int]) -> Int
{
    var B = [Int](repeating: 0, count: max(A.max()!, A.count)+1)

    for a in A {
        B[a] += 1
    }
    var sum = 0

    for i in 1...A.count {
        sum += B[i]
    }

    print(B)

    return A.count == sum ? 1 : 0
}
A = [4,1,3,2]
print("PermCheck: ", PermCheck(&A))

答案 31 :(得分:0)

我相信所有依赖于排序的解决方案都是错误的!因为所需的时间复杂度是O(N);并且排序不能是O(N)。

*哦,我的python解决方案是

df2 = df2.drop('name', 1).rename(columns={'price' : 'BBprice'})
df2

       id  BBprice
0  102984       50
1  847574       60

df1.merge(df2, on='id', how='left')

  name      id  price  BBprice
0   AG  102984     40     50.0
1   TY  847574     90     60.0
2   RE  213441     30      NaN

答案 32 :(得分:0)

简单解决方案100%

public static int solution(final int[] A) {

Set<Integer> set = new HashSet<Integer>();

for (int i : A) {
  set.add(i);
}

boolean numberNotFound = false;
for (int i = 1; i <= A.length; i++) {

//If set does not contain the number, that's the point to stop
//checking and return as per the boolean value set

  if (!set.contains(i)) {
    numberNotFound = true;
    break;
  }

}

return numberNotFound ? 0 : 1;
}

答案 33 :(得分:0)

一个简单而小巧的解决方案是:

public int solution(int[] A) {

        Arrays.sort(A);

        for (int i = 0; i < A.length; ++i) {
            if (A[i] != i + 1) {
                return 0;
            }
        }

        return 1;
}

尽管如此,我认为由于排序,最糟糕的时间复杂度将是O(nlgn)。

Codility给了我100分并计算出时间复杂度为O(n)......

答案 34 :(得分:0)

在这个测验中,Codility有点愚蠢: 使用此解决方案,我有100%的正确性和100%的性能

using System;

class Solution
{
    public int solution(int[] A)
    {
        Array.Sort(A);

        for (int i = 0; i < A.Length; i++)
        { 
            if (i+1 != A[i])
            {
                return 0;
            }
        }
        return 1;
    }
}

但它不应该通过性能测试 - 因为排序而是O(n * logn),所以它比O(n)更差。

答案 35 :(得分:0)

20%的表现得分..

function solution(a){
    a = a.sort();
    for(var i=0; i < a.length; i ++){
        if(a[i] != i + 1){
            return 0;
        } 
    }

return 1;

}

100%

function solution(a){
    a = a.sort((a,b) => a - b);
    for(var i=0; i < a.length; i ++){
        if(a[i] != i + 1){
            return 0;
        } 
    }

    return 1;
}

答案 36 :(得分:-1)

class Solution
{
    public int solution(int[] A)
    { 
       int count=0;**strong text**
       int n=A.length;


       for(int j=1;j<n;j++)
       {
           if(A[j]>A[0])
           A[0]=A[j];
       } 


       if(A[0]==A.length)
       {
           for(int i=1;i<=A[0];i++)
           {
               for(int j=0;j<A[0];j++)
               {
                    if(A[j]==i)
                    count++;
                }
            }
        }
        else
            return 0;

       if(count==A[0])
           return 1;
       else
           return 0;
    }
}

答案 37 :(得分:-1)

Python解决方案:

def solution(A):
    # write your code in Python 3.6
    if max(A)> len(A) or len(set(A))<len(A): 
        return 0
    else: 
        return 1