Python 我的Codekata解决方案提供了正确的解决方案,但在最终测试用例中遇到了性能问题
我用python3完成了我的算法,在codewars.com上解决了一个“codekata”。()我的代码正确且快速地解决了初始测试用例。但是,当提交给最终测试时,代码会因为花费太长时间来解决给定任务而超时 最初,我将for循环的内容实现为一个名为“calculate\u oddness\u level”的分离函数。我发现这比在for循环中实现要慢一些,所以我就这么做了 我知道在for循环中执行while循环并不是最佳性能。我想了好几次如何避免这种情况。但是,我需要确定列表中每个奇数的“奇数”级别。为了确定“级别”,需要一个循环,而且似乎比递归更快。因此,似乎除了在for循环中运行while循环之外,别无选择。然而,我通过立即将偶数指定为“奇数级别”0,消除了循环中的偶数 因此,我不知道如何才能在绩效方面取得任何显著的改进Python 我的Codekata解决方案提供了正确的解决方案,但在最终测试用例中遇到了性能问题,python,algorithm,numbers,Python,Algorithm,Numbers,我用python3完成了我的算法,在codewars.com上解决了一个“codekata”。()我的代码正确且快速地解决了初始测试用例。但是,当提交给最终测试时,代码会因为花费太长时间来解决给定任务而超时 最初,我将for循环的内容实现为一个名为“calculate\u oddness\u level”的分离函数。我发现这比在for循环中实现要慢一些,所以我就这么做了 我知道在for循环中执行while循环并不是最佳性能。我想了好几次如何避免这种情况。但是,我需要确定列表中每个奇数的“奇数”级
def oddest(a):
if len(a) == 0: return None
list_of_oddness_levels = []
for n in a:
if n % 2 == 0:
list_of_oddness_levels.append(0)
else :
level = 1
while True:
n = (n-1)/2
if n % 2 == 0 or n % 1 != 0:
break
else:
level += 1
list_of_oddness_levels.append(level)
print("adding Level!")
maximum = max(list_of_oddness_levels)
index_of_maximum = list_of_oddness_levels.index(maximum)
if list_of_oddness_levels.count(maximum) > 1:
return None
else:
return a[index_of_maximum]
根据最初的测试用例,我的代码应该能够正确地解决任务。然而,它的运行速度似乎慢了很多,因为它在最终提交时遇到了超时错误
我知道,可能会有一些简单的数学解决方案或5行高级代码利用一些python3库或我不知道的特殊函数。但是,最好采用详细、循序渐进且尽可能具有描述性的“干净代码”解决方案。- 您不需要列表,您可以使用O(1)个额外空间来完成
- 问题可能不是您的实现,而是-1。为什么?它是无限奇数,因为(-1-1)/2=-1。有趣的是,这是唯一一个这样的数字,所有其他的负数都有一个奇怪的级别1
- 对于正数,基本上是从右侧开始计算设置为1的连续位数,因此可以更快地使用掩码
公共整数奇数(int[]a){
如果(a==null | | a.length==0)
返回null;
//创建所需的31个掩码,最左边的位仅设置为负数
int[]掩码=新int[31];
掩码[0]=1;
对于(int i=1;i<31;i++)
掩码[i]=(掩码[i-1]>1;
if(n个掩码[mid]==掩码[mid])
左=中;
其他的
右=中;
}
级别=右侧;
}
}
如果(级别>最佳级别){
最佳数=n;
最佳水平=水平;
冲突=错误;
}else if(level==bestLevel&&n!=bestNumber){
冲突=真实;
}
}
如果(冲突)
返回null;
返回最佳编号;
}
在代码中使用可能会有所帮助。感谢您的时间、提示和代码示例。问题确实是“-1”。我刚刚解决了这个问题,将任何数字的奇怪度级别在某个点上降到-1,并将其指定为“999”。此时,最终的测试用例完成得相当快。
public Integer oddest(int[] a) {
if (a == null || a.length == 0)
return null;
// create the 31 masks needed, the left-most bit is only set for negative numbers
int[] masks = new int[31];
masks[0] = 1;
for (int i = 1; i < 31; i++)
masks[i] = (masks[i - 1] << 1) | 1; // masks[i - 1] * 2 + 1
int bestNumber = 0;
int bestLevel = 0;
boolean conflict = true;
for (int n : a) {
int level = 0;
if (n == -1) {
return -1;
} else if (n & 1 == 1) { // number is odd
if (n < 0) {
level = 1;
} else {
// now use the masks and bisection to find the oddity of positive numbers
int left = 0; // finally at the index of best matching mask
int right = 31; // never reached, finally left + 1
while (left + 1 < right) {
int mid = (left + right) >> 1;
if (n & masks[mid] == masks[mid])
left = mid;
else
right = mid;
}
level = right;
}
}
if (level > bestLevel) {
bestNumber = n;
bestLevel = level;
conflict = false;
} else if (level == bestLevel && n != bestNumber) {
conflict = true;
}
}
if (conflict)
return null;
return bestNumber;
}