前言
最近秋招做了很多笔试,小米、华为、携程、科大讯飞等等,这些笔试的系统一般是牛客或者赛码。笔试前做过leetcode或者剑指题库,但是到真实的考场上有些不一样。
一、题库练习
在leetcode中刷题时,我们直接根据题目要求的输入写进代码中,然后运行到给定的输出即可。
比如下面这个例子:
题目描述:给你一个字符串 s,找到 s 中最长的 回文子串。
示例 1:
输入:s = “babad”
输出:“bab”
解释:“aba” 同样是符合题意的答案。
示例 2:
输入:s = “cbbd”
输出:“bb”
代码如下(示例):
class Solution:
def longestPalindrome(self, s: str) -> str:
def expand_around_center(left: int, right: int) -> str:
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return s[left + 1:right]
max_palindrome = ""
if len(s) == 0:
return max_palindrome
for i in range(len(s)):
# 以 s[i] 为中心的最长回文子串
palindrome1 = expand_around_center(i, i)
if len(palindrome1) > len(max_palindrome):
max_palindrome = palindrome1
# 以 s[i] 和 s[i+1] 为中心的最长回文子串
if i + 1 < len(s):
palindrome2 = expand_around_center(i, i + 1)
if len(palindrome2) > len(max_palindrome):
max_palindrome = palindrome2
return max_palindrome
# 创建 Solution 实例
solution = Solution()
# 示例输入
s = "babad"
print(solution.longestPalindrome(s)) # 输出:"bab" 或 "aba"
这样在leetcode系统上是可以通过的,
但是在各大厂的在线考试系统的评判中并非自测样例通过就100分了
二、自测系统
牛客在线考试系统和赛码在线考试系统都是中国国内广泛使用的在线编程和评测平台,它们为求职者、学生和专业人士提供了一个练习编程技能和准备技术面试的环境。这些平台通常包含有各种难度级别的算法和编程题目,从基础的数据结构和算法问题到更复杂的题目。
牛客在线考试系统
牛客网(Nowcoder)是一个专注于程序员的在线学习和交流平台,提供在线编程题库、在线课程、技术讨论社区等服务。它的在线考试系统常用于企业招聘和技术竞赛。
赛码在线考试系统
赛码(SaiCode)也是一个提供在线编程练习和竞赛的平台,它支持多种编程语言,并提供自动评测系统,帮助用户检验代码的正确性和性能。
为什么自测样例通过了,系统自测时通过率低?
当你在这些平台上提交算法编程题时,可能会遇到自己测试的样例通过了,但系统自测时通过率很低的情况。
这种情况下,我们不能按自测示例在代码中赋固定的值,不需要创建 Solution 类的实例或调用方法。系统会自动实例化这个类并调用 longestPalindrome 方法,传入测试用例作为参数,并根据返回的结果来评估你的代码是否正确。我们不需要在代码中包含示例输入。代码应该直接计算并返回结果。
以下是适应在线考试系统会自动处理实例化和方法调用的代码:
def longestPalindrome(s: str) -> str:
def expand_around_center(left: int, right: int) -> str:
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return s[left + 1:right]
max_palindrome = ""
for i in range(len(s)):
# 以 s[i] 为中心的最长回文子串
palindrome1 = expand_around_center(i, i)
if len(palindrome1) > len(max_palindrome):
max_palindrome = palindrome1
# 以 s[i] 和 s[i+1] 为中心的最长回文子串
if i + 1 < len(s):
palindrome2 = expand_around_center(i, i + 1)
if len(palindrome2) > len(max_palindrome):
max_palindrome = palindrome2
return max_palindrome
# 读取输入
s = int(input())
result = longestPalindrome(s)
print("最长的回文子串是:", result)
# 在线考试系统将自动调用 longestPalindrome 函数并传入参数。
在这个版本中,longestPalindrome是一个独立的函数,而不是类的一个方法。这样,考试系统可以直接调用这个函数,并传入字符串s作为参数。函数会处理字符串并返回最长的回文子串。
再来个我遇见的真题:
题目描述:给出一个1至N的排列,每次操作可以将相邻的两个数交换,问能够得到的字典序最大的排列是什么?
例如:N = 8, {3 7 2 1 6 5 4 8},交换后,能够得到的字典序最大的排列为{7 3 6 5 2 1 8 4}。
题目思路:这个算法的核心思想是贪心选择当前可以交换到位置i的最大值,并且通过减少剩余的交换次数k来限制交换操作。
def move(arr, k):
for i in range(len(arr)):
max_index = i
for j in range(i + 1, min(len(arr), k + i + 1)):
if arr[j] > arr[max_index]:
max_index = j
# 将找到的最大值交换到当前位置
for j in range(max_index, i, -1):
arr[j], arr[j - 1] = arr[j - 1], arr[j]
# 更新剩余的交换次数
if k > max_index - i:
k -= max_index - i
else:
break
return arr
# 读取输入
n = int(input())
arr = list(map(int, input().split()))
# 初始交换次数k为数组长度的一半,因为每个元素可以交换两次
k = n // 2
# 调用函数并输出结果
print(" ".join(map(str, move(arr, k))))
这个程序中
- 读取数组长度:首先询问用户数组的长度。
- 读取数组元素:然后读取用户输入的一系列数字,这些数字由空格分隔。
- 输出结果:计算完成后,输出由空格隔开的数字。
这个示例简单地展示了如何读取用户输入并使用这些输入进行计算。
这种方式符合大多数在线编程平台的要求,它们通常会自动提供输入并捕获输出,所以你不需要在代码中包含任何输入/输出语句。只需关注算法逻辑即可。
但是测试通过率仍然偏低,可能是以下原因造成:
-
测试用例差异:你可能只测试了几个样例,而这些样例可能没有覆盖到所有的边界条件或特殊情况。在线考试系统的测试用例通常更加全面和严格,可能会包含你没有考虑到的输入。
-
代码错误:可能存在逻辑错误或实现错误,这些错误在少数几个测试样例中没有暴露出来,但在更广泛的测试用例中就会显现。
-
性能问题:你的代码可能在小规模数据上表现良好,但在处理大规模数据时会出现超时或内存溢出等问题。
-
理解题意:可能对题目的理解有误,导致实现的算法或逻辑不符合题目要求。
-
随机性:如果题目涉及到随机性,你的代码可能在某些情况下无法正确处理。
-
隐含条件:有时候题目中可能存在一些没有明确说明的隐含条件,这些条件在系统测试中可能会被检查到。
如何提高通过率?
- 全面测试:使用多种不同的测试用例,包括边界条件和极端情况。
- 代码审查:仔细检查代码逻辑,确保没有实现错误。
- 性能优化:优化算法和数据结构,确保代码在时间和空间复杂度上都是高效的。
- 理解题目:确保完全理解题目要求,必要时可以重新阅读题目描述或示例。
- 学习讨论:参考其他用户的讨论和解答,了解不同的解题思路和方法。
以上太宽泛了,让我们举几个实际的例子
1. 在代码中添加异常处理
可以帮助你处理在执行过程中可能发生的各种错误情况,如类型错误、值错误或其它意外情况。在Python中,你可以使用try-except块来实现异常处理。
def longestPalindrome(s: str) -> str:
def expand_around_center(left: int, right: int) -> str:
try:
while left >= 0 and right < len(s) and s[left] == s[right]:
left -= 1
right += 1
return s[left + 1:right]
except Exception as e:
# 打印错误信息,也可以记录日志或进行其他错误处理
print(f"Error during expanding around center: {e}")
# 可以选择返回一个空字符串或者合适的默认值
return ""
max_palindrome = ""
try:
for i in range(len(s)):
# 以 s[i] 为中心的最长回文子串
palindrome1 = expand_around_center(i, i)
if len(palindrome1) > len(max_palindrome):
max_palindrome = palindrome1
# 以 s[i] 和 s[i+1] 为中心的最长回文子串
if i + 1 < len(s):
palindrome2 = expand_around_center(i, i + 1)
if len(palindrome2) > len(max_palindrome):
max_palindrome = palindrome2
except Exception as e:
# 处理可能发生的任何异常
print(f"Error processing the string: {e}")
return ""
return max_palindrome
# 测试代码
if __name__ == "__main__":
test_string = "babad"
print(longestPalindrome(test_string)) # 应该输出 "bab" 或 "aba"
2.编写测试函数
-
单元测试:
- 编写针对函数或方法的单元测试,确保它们在预期的输入下能返回正确的输出。
- 使用测试框架(如Python的
unittest
或pytest
)来自动化测试过程。
-
边界值分析:
- 测试函数能够处理的最小和最大可能值。
- 对于字符串处理函数,考虑空字符串、单个字符、非常长的字符串等。
def test_longest_palindrome():
assert longestPalindrome("babad") in ["bab", "aba"]
assert longestPalindrome("cbbd") == "bb"
assert longestPalindrome("") == ""
assert longestPalindrome("a") == "a"
assert longestPalindrome("aaa") == "aaa"
assert longestPalindrome("palindrome") == "mna"
assert longestPalindrome("racecar") == "racecar"
assert longestPalindrome("abccba") == "abccba"
# 测试边界条件和异常输入
try:
longestPalindrome(123) # 非字符串输入
except Exception as e:
assert isinstance(e, TypeError)
# 测试非常长的字符串
long_string = "a" * 1000
assert longestPalindrome(long_string) == long_string
# 打印测试结果
print("All tests passed!")
# 运行测试函数
test_longest_palindrome()
总结
在实际的在线笔试系统中,我们不能按自测示例在代码中赋固定的值,不需要创建 Solution 类的实例或调用方法。系统会自动实例化这个类并调用 方法,传入测试用例作为参数,并根据返回的结果来评估你的代码是否正确。
另外,通过运行测试用例,我们可以验证我们的是否能够正确处理各种输入,包括正常值、边界值和错误输入。基本上评判编程题的标准是通过率的高低,如果所有测试用例都通过,我们可以更有信心地认为我们的代码是高分的。