诚征大神求解codility上两个测试题,智力和能力大考验!(我是被打击惨了,看看大神们如何吧)
不说了,有机会在codility上做了两个测试题,用php解。我写了两个程序,当时感觉还行,但出来结果一看,200分就得了50分。诚征大神指出我的程序中的错误,以及大神们的solution.
啥都不说了,先上题目:
1. You are given a non-empty zero-indexed array A consisting of N integers. Each element of array A can be ?1, 0 or 1.
A pair of integers (P, Q), such that 0 ≤ P ≤ Q
You are given integer S. The goal is to find the largest slice whose sum equals S.
For example, consider integer S = 2 and array A such that:
A[0] = 1
A[1] = 0
A[2] = -1
A[3] = 1
A[4] = 1
A[5] = -1
A[6] = -1
There are exactly two slices (0, 4) and (3, 4) whose sum equals 2. The largest such slice is (0, 4) and its length equals 5.
Write a function:
function solution($A, $S);
that, given a non-empty zero-indexed array A consisting of N integers and an integer S, returns the length of the largest slice whose sum equals S.
The function should return ?1 if there is no such slice.
For example, given S = 2 and:
A[0] = 1
A[1] = 0
A[2] = -1
A[3] = 1
A[4] = 1
A[5] = -1
A[6] = -1
the function should return 5, as explained above.
Assume that:
N and S are integers within the range [1..100,000];
each element of array A is an integer within the range [?1..1].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
2.A non-empty zero-indexed array A consisting of N integers is given.
You can perform a single swap operation in array A. This operation takes two indices I and J, such that 0 ≤ I ≤ J
The goal is to check whether array A can be sorted into non-decreasing order by performing only one swap operation.
For example, consider array A such that:
A[0] = 1
A[1] = 3
A[2] = 5
A[3] = 3
A[4] = 7
After exchanging the values A[2] and A[3] we obtain an array [1, 3, 3, 5, 7], which is sorted in non-decreasing order.
Write a function:
function solution($A);
that, given a non-empty zero-indexed array A consisting of N integers, returns true if the array can be sorted into non-decreasing order by one swap operation or false otherwise.
For example, given:
A[0] = 1
A[1] = 3
A[2] = 5
A[3] = 3
A[4] = 7
the function should return true, as explained above.
On the other hand, for the following array:
A[0] = 1
A[1] = 3
A[2] = 5
A[3] = 3
A[4] = 4
the function should return false, as there is no single swap operation that sorts the array.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [1..1,000,000,000].
Complexity:
expected worst-case time complexity is O(N*log(N));
expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
我的程序:
针对第一题:
function solution($A, $S) { // write your code in PHP5.3 $len = count($A); $slice = -1; for ($begin=0; $begin<$len;$begin++) { $total = 0; for ($end = $begin; $end < $len; $end ++) { $total = $total + $A[$end]; if ($total == $S) { $temp = $end - $begin +1; if ($temp > $slice) { $slice = $temp; } } } } return $slice;}
针对第二题:
function solution($A) { // write your code in PHP5.3 $arr = array(); $len = count($A); $check = false; for ($i=0;$i<$len-1;$i++) { $arr = $A; for ($j=$i+1;$j<$len;$j++) { $temp = $arr[$j]; $arr[$j] = $arr[$i]; $arr[$i] = $temp; $no_decrease = true; for ($k=1;$k< $len;$k++) { if ($arr[$k]<$arr[$k-1]) { $no_decrease = false; } } if ($no_decrease == true) { $check = true; } } } return $check; }
我是被打击惨了,最后200分中只得了50分。大神们,你们能得到多少分?
回复讨论(解决方案)
尼玛,仔细一看,第二题我的程序就有个明显错误,$arr = $A;应该放在第二个 for 的后面。
晕死。
不识英语。。 0分
第天回贴即可获得10分可用分
就没有大神能来解决么? 尤其第二道题,还是蛮有难度的。
先看第二题
原代码计算结果是正确的,而#1的补充是错误的!
如果将 $arr = $A; 放在第二个 for 的后面那么将出现一系列的使用未定义变量的警告
解答被扣分的原因在于你的答案不符合:时间复杂度为 O(N*log(N)) 的要求
可以写作这样
var_dump(solution([1,3,5,3,7]));var_dump(solution([1,3,5,3,4]));function solution($A) { $arr = array(); $len = count($A); $check = 0; for($i=0;$i<$len-1;$i++) { if($A[$i+1] < $A[$i]) { $temp = $A[$i+1]; $A[$i+1] = $A[$i]; $A[$i] = $temp; if($i > 0 && $A[$i-1] <= $A[$i]) $check++; } } return $check == 1;}
bool(true)bool(false)
再看第一题
同样计算的结果并没有错误,只是算法没有符合:时间复杂度为 O(N) 的要求
你使用了双重循环,所以时间复杂度为 O(N*N)
可以用闭包来去掉一重循环
var_dump(solution([1,0,-1,1,1,-1,-1], 2));function solution($A, $S) { $len = count($A); $slice = -1; for ($begin=0; $begin<$len; $begin++) { $total = 0; array_walk($A, function($v, $end, $S) use ($begin, &$slice, &$total) { if($end < $begin) return; $total += $v; if($total == $S) { $temp = $end - $begin + 1; if ($temp > $slice) $slice = $temp; } }, $S); } return $slice;}
感谢版主大驾光临啊。
不过对于第二题,我有不同看法:
1.你的思路是:检查相邻两个大小,若右边的小于左边的数值,则调换;且这种调换满足i左边的大小关系,则check++.
事实上,我在做题时考虑过这个思路,不过考虑这个例子:1,6,3,4,3,7.只要把6和第二个3调换一下,则可以满足非降数列,最后应该是true。但是,按照你的算法,这个题目返回false。
关键点是:数字的调换可以是很巧妙的一次调换。
2.第二题中,$arr = $A;应该放在第二个for后面,我又验证了一遍,不会出现未定义对象等错误。结果是正确的。
我的思路是每次把$A赋值给$arr,并且采用穷举法把任意两个不同数字调换一次,判断调换后的结果是不是非降数列。是的话,返回true,否的话,不改变check的false值。只要穷举法中,任意一次可以做到,check的值就变为true.
这个思路是正确的,但就是时间复杂度不满足,扣分了。
版主,你看呢?
先看第二题
原代码计算结果是正确的,而#1的补充是错误的!
如果将 $arr = $A; 放在第二个 for 的后面那么将出现一系列的使用未定义变量的警告
解答被扣分的原因在于你的答案不符合:时间复杂度为 O(N*log(N)) 的要求
可以写作这样
var_dump(solution([1,3,5,3,7]));var_dump(solution([1,3,5,3,4]));function solution($A) { $arr = array(); $len = count($A); $check = 0; for($i=0;$i<$len-1;$i++) { if($A[$i+1] < $A[$i]) { $temp = $A[$i+1]; $A[$i+1] = $A[$i]; $A[$i] = $temp; if($i > 0 && $A[$i-1] <= $A[$i]) $check++; } } return $check == 1;}
bool(true)bool(false)
版主第一题的解法,我验证过,确实正确,感觉用这个巧妙的函数去掉一次循环。
我查了array_walk的介绍,还不能理解版主精妙的思路。版主能否提点两句?
还有,第二个题目,调整后的代码如下,供版主以及其他大神测试用
$arr = array();$len = count($A);$check = false; for ($i=0;$i<$len-1;$i++){ for ($j=$i+1;$j<$len;$j++) { $arr = $A; $temp = $arr[$j]; $arr[$j] = $arr[$i]; $arr[$i] = $temp; $no_decrease = true; for ($k=1;$k< $len;$k++) { if ($arr[$k]<$arr[$k-1]) { $no_decrease = false; } } if ($no_decrease == true) { $check = true; } }}return $check;
再看第一题
同样计算的结果并没有错误,只是算法没有符合:时间复杂度为 O(N) 的要求
你使用了双重循环,所以时间复杂度为 O(N*N)
可以用闭包来去掉一重循环
var_dump(solution([1,0,-1,1,1,-1,-1], 2));function solution($A, $S) { $len = count($A); $slice = -1; for ($begin=0; $begin<$len; $begin++) { $total = 0; array_walk($A, function($v, $end, $S) use ($begin, &$slice, &$total) { if($end < $begin) return; $total += $v; if($total == $S) { $temp = $end - $begin + 1; if ($temp > $slice) $slice = $temp; } }, $S); } return $slice;}
对于第二题,我只是根据题目的示例而为之,的确没有考虑的 交换的位置不相邻的情况
所以也在纳闷为何是 O(N*log(N)) 呢?O(N)) 不就可以了吗
改写一下
var_dump(solution([1,3,5,3,7]));var_dump(solution([1,3,5,3,4]));var_dump(solution([1,6,3,4,3,7])); function solution($A) { $arr = array(); $len = count($A); $check = 0; for($i=0;$i<$len-1;$i++) { if($A[$i+1] < $A[$i]) { $flag = 0; for($j=$i+1; $j<$len-1; $j++) { if($A[$i] < $A[$j+1]) { $flag = 1; break; } } $temp = $A[$j]; $A[$j] = $A[$i]; $A[$i] = $temp; if($i > 0 && $A[$i-1] <= $A[$i]) $check++; if(! $flag) $i--; } } return $check == 1;}
bool(true)bool(false)bool(true)
时间复杂度的简单判断
for() {
code
}
==> O(N)
for() {
code
for() {
code
}
}
==> O(N*log(N))
for() {
for() {
code
}
}
==> O(N*N)
仔细测试了一下你的代码。短时间还没有办法理解版主的思路,不过我多测试了几个例子,大部分正确,但依然有问题。
比如这个例子,var_dump(solution([1,6,5,3,3,4,7]));
目测应该无法一次调换成功,但程序返回是正确的。
因为暂时还没有理解版主大神的思路,所以还不好评论,但我一直担心non-decreasing 非降,其中包括等号=的情况,比如下面
if($A[$i] < $A[$j+1]) {
$flag = 1;
break;
}
其中,$A[$i] < $A[$j+1]是否需要等号呢?
我提供的测试例子是不是应该返回false呢?
对于第二题,我只是根据题目的示例而为之,的确没有考虑的 交换的位置不相邻的情况
所以也在纳闷为何是 O(N*log(N)) 呢?O(N)) 不就可以了吗
改写一下
var_dump(solution([1,3,5,3,7]));var_dump(solution([1,3,5,3,4]));var_dump(solution([1,6,3,4,3,7])); function solution($A) { $arr = array(); $len = count($A); $check = 0; for($i=0;$i<$len-1;$i++) { if($A[$i+1] < $A[$i]) { $flag = 0; for($j=$i+1; $j<$len-1; $j++) { if($A[$i] < $A[$j+1]) { $flag = 1; break; } } $temp = $A[$j]; $A[$j] = $A[$i]; $A[$i] = $temp; if($i > 0 && $A[$i-1] <= $A[$i]) $check++; if(! $flag) $i--; } } return $check == 1;}
bool(true)bool(false)bool(true)
if($i > 0 && $A[$i-1] <= $A[$i]) $check++; //交换成功,记录
else return false; //交换失败,返回。 原先漏掉了
if($A[$i] < $A[$j+1]) {
$flag = 1;
break;
}
的意思是找到第一个大于 $A[$i] 的位置
要不要等号无所谓
修改后如下
var_dump(solution([1,3,5,3,7]));var_dump(solution([1,3,5,3,4]));var_dump(solution([1,6,3,4,3,7]));var_dump(solution([1,6,5,3,3,4,7])); function solution($A) { $arr = array(); $len = count($A); $check = 0; for($i=0;$i<$len-1;$i++) { if($A[$i+1] < $A[$i]) { //如果降序 $flag = 0; for($j=$i+1; $j<$len-1; $j++) { //向后找到符合升序的位置 if($A[$i] < $A[$j+1]) { $flag = 1; break; } } $temp = $A[$j]; //交换 $A[$j] = $A[$i]; $A[$i] = $temp; if($i > 0 && $A[$i-1] <= $A[$i]) $check++; //交换成功 else return false; //交换失败 if(! $flag) $i--; // $flag = 0 表示前面的查找是自然结束的,有待商榷 } } return $check == 1;}
毫无疑问,xuzuning 版主是我心目中努力的一个目标,程序算法犀利无比,再一次感受到啊。
啥也别说,肯定100分啊。
对了,我查了一些资料,在引用codility题目时一般都隐去题目,因为涉及到版权问题。所以,xuzuning版主,是不是把题目具体文字隐去?或者其他方式处理? 只是建议啊。
修改后如下
var_dump(solution([1,3,5,3,7]));var_dump(solution([1,3,5,3,4]));var_dump(solution([1,6,3,4,3,7]));var_dump(solution([1,6,5,3,3,4,7])); function solution($A) { $arr = array(); $len = count($A); $check = 0; for($i=0;$i<$len-1;$i++) { if($A[$i+1] < $A[$i]) { //如果降序 $flag = 0; for($j=$i+1; $j<$len-1; $j++) { //向后找到符合升序的位置 if($A[$i] < $A[$j+1]) { $flag = 1; break; } } $temp = $A[$j]; //交换 $A[$j] = $A[$i]; $A[$i] = $temp; if($i > 0 && $A[$i-1] <= $A[$i]) $check++; //交换成功 else return false; //交换失败 if(! $flag) $i--; // $flag = 0 表示前面的查找是自然结束的,有待商榷 } } return $check == 1;}

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Python에서 최소 공배수를 찾는 알고리즘을 작성하는 방법은 무엇입니까? 최소공배수는 두 숫자를 나눌 수 있는 두 숫자 사이의 가장 작은 정수입니다. 수학에서 최소 공배수를 푸는 것은 기본적인 수학적 작업이며, 컴퓨터 프로그래밍에서는 Python을 사용하여 최소 공배수를 푸는 알고리즘을 작성할 수 있습니다. 다음은 기본적인 최소 공배수 알고리즘을 소개하고 구체적인 코드 예제를 제공합니다. 최소 공배수의 수학적 정의는 다음과 같습니다. a가 n으로 나누어지고 b가 n으로 나누어지면 n은 a와 b의 최소 공배수입니다. 최소값을 해결하려면

Numpy는 Python의 잘 알려진 과학 컴퓨팅 라이브러리로, 대규모 다차원 배열 및 행렬을 처리하기 위한 풍부한 기능과 효율적인 컴퓨팅 방법을 제공합니다. 데이터 과학 및 기계 학습의 세계에서 행렬 반전은 일반적인 작업입니다. 이번 글에서는 Numpy 라이브러리를 이용하여 역행렬을 빠르게 푸는 방법을 소개하고 구체적인 코드 예시를 제공하겠습니다. 먼저 Numpy 라이브러리를 설치하여 Python 환경에 도입해 보겠습니다. Numpy는 다음 명령을 사용하여 터미널에 설치할 수 있습니다: pipinsta

Windows 시스템에 관해 말하자면, 많은 사람들이 이제 Windows 시스템을 사용하고 있으며 Windows에는 win7 및 win8.1을 포함한 여러 시스템 버전이 포함되어 있다고 생각합니다. 일부 네티즌들은 win7과 8.1 중 어느 시스템을 선택해야 할지 모릅니다. win7과 8.1 중 어느 것이 더 낫습니까? 마스터는 win7과 win8.1의 차이점과 선택 사항을 알려줄 것입니다. Windows8.1은 멋진 인터페이스를 가지고 있습니다. 하지만 개선된 부분도 더 크고 단점도 더 큽니다. 더 분명한 것에는 흐릿한 게임 글꼴과 메모리 부족 버그가 포함됩니다. 메모리가 아무리 크더라도 일부 게임을 실행할 때 메모리가 부족하여 종료해야 한다는 메시지가 표시됩니다. 실제로 검사 당시 기억력은 정상이었다. 하나는 메모리 관리 메커니즘에 문제가 있다는 것이고, 다른 하나는

제목: C 언어 프로그래밍을 사용하여 최대 공약수 솔루션 구현 최대 공약수(Greatest Common Divisor, 줄여서 GCD)는 두 개 이상의 정수를 동시에 나눌 수 있는 가장 큰 양의 정수를 말합니다. 최대 공약수를 구하는 것은 일부 알고리즘 및 문제 해결에 매우 도움이 될 수 있습니다. 본 글에서는 최대공약수를 찾는 기능을 C언어 프로그래밍을 통해 구현하고, 구체적인 코드 예시를 제공하겠습니다. C 언어에서는 유클리드 알고리즘을 사용하여 최대값을 풀 수 있습니다.

Python을 사용하여 계승 해결 알고리즘을 구현하는 방법은 무엇입니까? 팩토리얼(Factorial)은 수학에서 중요한 개념입니다. 즉, 숫자에 자신의 마이너스 1을 곱한 다음 마이너스 1을 곱하고 계속해서 1이 되는 것을 의미합니다. 팩토리얼은 일반적으로 "!" 기호로 표시됩니다. 예를 들어 5의 팩토리얼은 5!로 표시되며 계산식은 5!=5×4×3×2×1=120입니다. Python에서는 루프를 사용하여 간단한 계승 알고리즘을 구현할 수 있습니다. 샘플 코드는 다음과 같습니다.

초보자에서 마스터까지: Go 언어 프로젝트 개발 경험 공유 최근 몇 년 동안 Go 언어는 단순성과 효율성으로 인해 개발자들 사이에서 점점 더 인기를 얻고 있습니다. 오픈소스 프로그래밍 언어인 Go는 강력한 동시성, 정적 유형 검사, 자동화된 메모리 관리 등의 장점을 갖고 있어 많은 대형 인터넷 기업에서 선호하고 있습니다. 처음부터 Go를 배우기 시작한 초보 개발자로서, 프로젝트 개발 과정에서 계속 탐색하고 배우며 점차 Go 프로젝트를 독립적으로 개발할 수 있는 마스터로 성장했습니다. 오늘은 여러분과 함께 논의하겠습니다. 큰

C 언어에서 최대 공약수를 찾는 방법을 배우려면 특정 코드 예제가 필요합니다. 최대 공약수(최대 공약수, 줄여서 GCD)는 이를 나눌 수 있는 두 개 이상의 정수 중에서 가장 큰 양의 정수를 나타냅니다. 최대 공통 분모는 특히 분수를 다루고, 분수를 단순화하고, 가장 간단한 정수 비율과 같은 문제를 해결할 때 컴퓨터 프로그래밍에서 자주 사용됩니다. 이 기사에서는 C 언어를 사용하여 최대 공약수를 찾는 방법을 소개하고 구체적인 코드 예제를 제공합니다. 최대 공약수를 푸는 방법에는 유클리드와 같은 여러 가지 방법이 있습니다.

거의 한 달 간의 침묵 끝에 마침내 당 삼촌이 다시 목소리를 냈고, 이번에는 블리자드 국가 서버의 미래에 대한 엄청난 축복이라고 할 수 있습니다. 1. 삼촌이 블록버스터 뉴스를 많이 냈어요. 드디어 새 삼촌을 기대하고 있어요. 게다가 NGA의 총알에도 불구하고 그는 6일 동안 차단당했습니다. 평판과 명성 2점. 이것은 내 인생에서 결코 암실에서 나오지 않을 것이라고 할 수 있습니다. 삼촌은 자신의 메시지가 이전 NetEase 운영 및 유지 관리 담당자로부터 왔다며 리콜 이메일을 직접 보여주었다고 말했습니다. 회사는 현재 청두에 있으며 준비가 순조롭게 진행되고 있으며 서버는 2~3년 안에 출시될 예정입니다. 삼 개월. 데이터 저장에는 문제가 없지만, 유골함을 사용해본 플레이어의 경우 유골 데이터가 저장되지 않는 경우 작은 문제가 있습니다.
