我正在努力解决编码练习的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不是我所期待的。我知道有很多解决方案,但我想知道解决方案的问题是什么。我错过了什么角落的案例。结果页面不显示上述解决方案失败的输入列表。
答案 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
。如果我们发现任何B
为B[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 = 0
和0 ^ 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