PermCheck协同性.O(N)时间复杂性
本文关键字:时间复杂性 PermCheck | 更新日期: 2023-09-27 18:29:57
嗨,我有这个PermCheck codility的解决方案。以下是包含以下问题的链接:https://codility.com/demo/results/demo73YNCU-8FK/
我得到了100%,但我得到了O(N*log(N))或O(N)的时间复杂性。我怎样才能使这个代码为O(N)?你能简要描述一下代码O(N)的由来吗?谢谢。
此处的快捷方式代码:
Array.Sort(A);
if(A[0] == 1 && A.Length == 1) return 1;
if(A[0] != 1) return 0;
int n = 0;
for(int i = 0; i < A.Length; i++)
{
if(i < A.Length - 1)
{
if(A[i+1] == A[i] + 1)
{
n += 1;
}
else
{
return 0;
}
}
}
return 1;
创建一个与输入大小相同的bool数组N,并将所有元素保留为默认的false值。循环输入的每个元素X。如果X大于N,则返回false。如果数组[N-1]为true,则返回false。否则,将array[N-1]设置为true。重复这是O(N)。
解释:首先,如果你有一个置换,那么你需要元素1..N,但如果任何元素大于N,那么肯定会缺少一些元素。其次,如果一个元素出现两次,那就是一个问题,这就是为什么我们创建bool数组来记住已经看到的元素。
我的python解决方案(不需要额外的库,看起来像python,别人也不难理解):
def solution(A): return 1 if len(set(A)) == len(A) == sorted(A)[-1] else 0
可以简化为:
def solution(A):
if len(set(A)) == len(A):
if len(A) == sorted(A)[-1]:
return 1
return 0
我检查了两个时刻:
1:数组中集合的长度(集合不能有重复项)等于初始数组的长度
传递的数组(无重复):[1,3,2,4],[4,3,2,5]
阵列失败:[1,1,2,4],[5,6,6,1]
2:初始数组的长度等于排序数组中的最后一个元素
传递的数组:[1,2,3,4]:长度等于最后一个元素=>返回1
阵列失败:[2,3,4,5]:长度不等于最后一个元素=>返回0
如果A包含0或负元素,则此代码不起作用,但根据任务详细信息:数组A的每个元素都是[1..1000000000]范围内的整数。
Codibility显示100%和O(N)或O(N*log(N))
尝试使其成为O(N)(由fejesjoco建议):
def solution(A):
array_length = len(A)
seen_values = [False] * array_length
for x in A:
if x > array_length:
return 0
else:
if seen_values[x - 1]:
return 0
else:
seen_values[x - 1] = True
return 1
Codibility result 100%检测到的时间复杂度:O(N)或O(N*log(N))
两种代码显示出相同的结果和时间复杂性。也许共同性不能正确评估它?
这是我的100/100答案:
与@fejesjoco 理念相同
https://codility.com/demo/results/demoNR485D-33P/
您可以将int更改为long以获得性能。
public int solution(int[] A) { // idea: add to set,dictionary. Count the size and compare to N. // dedupe data when needed. var set = new HashSet<int>(); var max = int.MinValue; foreach (var item in A) { if (set.Contains(item)) return 0; set.Add(item); if (item > max) max = item; } return set.Count == max ? 1 : 0; }
这是我的解决方案,正确性和性能都达到了100%。
def解决方案(A):阵列强度=len(A)
if (arraylength > 100000):
raise ValueError("Out of bound range")
arr = sorted(A)
for i in range(arraylength):
if (arr[i] != i+1):
return 0
return 1
我知道这个问题很久以前就被问过了,但它仍然活跃在协同性中。
可能的解决方案:
public int solution(int[] A)
{
return (Enumerable.Range(1, A.Length).Except(A).Count() == 0) ? 1 : 0;
}
根据fejesjoco的建议,
Boolean[] bln = new Boolean[A.Length];
for (int i = 0; i < A.Length; i++)
{
if (A[i] > A.Length) // more than array length
return 0;
if (bln[A[i]-1]) // same value twice
return 0;
bln[A[i]-1] = true;
}
return 1;
这是我的解决方案,它的得分为100%。不要忘记添加";使用System.Linq";。
int distinctLength = A.Distinct().ToArray().Length;
// The array length should equal to the distinct array length which is also the maximum value in array A.
if (A.Length == distinctLength && distinctLength == A.Max()) { return 1; }
return 0;
Swift Solution 100%
public func solution(_ A : inout [Int]) -> Int {
// write your code in Swift 4.2.1 (Linux)
let sorted = A.sorted()
for (index, value) in sorted.enumerated() {
if index+1 != value {
return 0
}
}
return 1
}