形式 | 章节 | 描述 |
---|---|---|
知识点 | 算法性能评估 | 时间复杂度、空间复杂度 |
知识点 | 递归算法 | 使用递归算法替代传统循环 |
霍格沃兹测试开发
是通过大厂面试的必备硬核能力
是升职加薪必备的基础能力
是成为高阶测试开发工程师的必经之路
阿里巴巴招聘需求:
字节测试开发实习生招聘需求:
形式 | 章节 |
---|---|
知识点 | 顺序查找 |
知识点 | 二分查找 |
第一次刷题
def binary_search(nums, target: int) -> int:
"""
在有序数组arr中查找目标元素target
返回目标元素的索引,如果目标元素不存在,则返回-1
"""
# low 和 high 用于跟踪要在其中查找的列表的部分
low = 0
high = len(nums)-1
while low <= high:
mid = (low + high) // 2
guess = nums[mid]
if guess == target:
return mid
# 猜的数字小了。
elif guess < target:
low = mid - 1
# 猜的数字大了。
else:
high = mid + 1
# 没有制定的元素。
return -1
# 功能和顺序查找一致,但是效率高很多。
def test_binary_search_null():
assert binary_search([1, 3, 4, 5, 7, 8], "a") == -1
# 存在返回对应数据的索引
def test_binary_search():
assert binary_search([1, 3, 4, 5, 7, 8], 1) == 0
// 二分查找的实现
public class BinarySearch {
public int binarySearch(int[] nums, int target) {
int minIndex = 0;
int maxIndex = nums.length - 1;
while (minIndex <= maxIndex) {
int mid = (minIndex + maxIndex) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] > target) {
maxIndex = mid - 1;
} else {
minIndex = mid + 1;
}
}
return -1;
}
}
// 测试用例
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class BinarySearchTest {
@Test
void binarySearch() {
BinarySearch bb = new BinarySearch();
int[] arr = {11, 22, 33, 44, 55, 66, 77};
int[] arr2 = {11, 22, 33, 44, 55, 66, 77, 88};
assert bb.binarySearch(arr, 33) == 2;
// 不存在的场景
assert bb.binarySearch(arr, 99) == -1;
// 边界值
assert bb.binarySearch(arr, 11) == 0;
assert bb.binarySearch(arr, 77) == 6;
assert bb.binarySearch(arr2, 88) == 7;
}
}
形式 | 章节 |
---|---|
知识点 | 冒泡排序 |
知识点 | 递归算法 |
知识点 | 快速排序 |
冒泡排序虽然简单,但其具有一定的应用场景。对于小规模的序列,冒泡排序可以快速地实现排序,并且由于其基本操作是交换相邻元素,因此它也是一种稳定的排序算法。此外,冒泡排序也有助于理解排序算法的基本原理和思想,是学习排序算法的入门内容。
def bubble_sort(arr):
n = len(arr)
for i in range(n):
print(f"第{i}轮遍历")
for j in range(n - i - 1):
print(f"===第{j}轮比较排序===")
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
def test_bubble_sort():
assert bubble_sort([5,1,3,2,6]) == [1,2,3,5,6]
// 冒泡排序的实现
public class Sort {
public int[] bubbleSort(int[] originList) {
for (int j = 0; j < originList.length - 1; j++) {
for (int i = 0; i < originList.length - 1; i++) {
if (originList[i] > originList[i + 1]) {
int tmp = originList[i];
originList[i] = originList[i + 1];
originList[i + 1] = tmp;
}
}
}
System.out.println(Arrays.toString(originList));
return originList;
}
}
// 测试用例
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import static org.junit.jupiter.api.Assertions.*;
class SortTest {
static Sort sort;
@BeforeAll
static void setUp(){
sort = new Sort();
}
@Test
void bubbleSort() {
int[] arr = {5, 2, 9, 8, 1, 3, 6};
int[] arr2 = {5, 2, 9, 8, 1, 3, 6};
Arrays.sort(arr2);
sort.bubbleSort(arr);
assertEquals(Arrays.toString(arr), Arrays.toString(arr2));
}
}
# Python 版本
def factorial_iterative(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
// Java版本
public class Recursion {
public int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
}
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。即为
n!=1×2×3×...×(n-1)×n
。
输入 | 输出 |
---|---|
1 | 1 |
2 | 2 |
3 | 6 |
4 | 24 |
n | 1×2×3×…×(n-1)×n |
n<=1
# Python 版本的实现
def factorial_recursive(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial_recursive(n - 1)
// Java版本的实现
public class Recursion {
public int factorial_recursive(int n) {
if (n == 0 || n == 1) {
return 1;
}
return n * factorial_recursive(n - 1);
}
}
public class Recursion {
// 通过递归找到列表中最大的数字。
public int getSum(int [] nums, int sum, int currentIndex){
if (currentIndex==nums.length){
return sum;
}
sum += nums[currentIndex];
currentIndex += 1;
return getSum(nums, sum, currentIndex);
}
// 通过递归找到列表中最大的数字。
public int getMax(int [] nums, int maxData, int currentIndex){
if (currentIndex==nums.length){
return maxData;
}
if (nums[currentIndex] > maxData){
maxData = nums[currentIndex];
}
currentIndex += 1;
return getMax(nums, maxData, currentIndex);
}
// 递归版本的二分查找
public int recurisonBinarySearch(int [] nums, int target ,int minIndex , int maxIndex, int mid){
mid = (minIndex+maxIndex)/2;
if (nums[mid] == target){
return mid;
}
if (minIndex>maxIndex){
return -1;
}
if (nums[mid]>target) {
maxIndex = mid - 1;
}else {
minIndex = mid + 1;
}
return recurisonBinarySearch(nums, target, minIndex, maxIndex, mid);
}
}
// 测试用例
class RecursionTest {
static Recursion recursion;
@BeforeAll
static void setupClass(){
recursion = new Recursion();
}
@Test
void getSum() {
int [] xx = {1,2,3,4,5};
int [] xx2 = {1,2,3,4,5,6,7};
assertEquals(recursion.getSum(xx, 0, 0) , 15);
assertEquals(recursion.getSum(xx2, 0, 0) , 28);
}
@Test
void getMax() {
int [] xx = {1,2,3,4,5};
int [] xx2 = {1,2,3,4,5,6,7};
assertEquals(recursion.getMax(xx, xx[0], 0) , 5);
assertEquals(recursion.getMax(xx2, xx2[0], 0) , 7);
}
@Test
void recurisonBinarySearch() {
int[] arr = {11, 22, 33, 44, 55, 66, 77};
int[] arr2 = {11, 22, 33, 44, 55, 66, 77, 88};
assert recursion.recurisonBinarySearch(arr, 33, 0, arr.length - 1, 0) == 2;
// 不存在的场景
assert recursion.recurisonBinarySearch(arr, 99, 0, arr.length- 1, 0) == -1;
// 边界值
assert recursion.recurisonBinarySearch(arr, 11, 0, arr.length- 1, 0) == 0;
assert recursion.recurisonBinarySearch(arr, 77, 0, arr.length- 1, 0) == 6;
assert recursion.recurisonBinarySearch(arr2, 88, 0, arr2.length- 1, 0) == 7;
}
}
# 1. 编写一个递归函数来计算列表包含的元素数。
def count_item(data_list, count):
if data_list == []:
return count
data_list.pop(0)
count += 1
# 递归条件
return count_item(data_list, count)
def test_count_item():
assert count_item([1,2,3,4,5], 0) == 5
# 1. 通过递归找到列表中最大的数字。
def find_max_number(data_list, max_data):
# 基线条件
if data_list == []:
return max_data
delete_item = data_list.pop(0)
if max_data < delete_item:
max_data = delete_item
# 递归条件
return find_max_number(data_list, max_data)
def test_find_max_number():
data_list = [1,2,3,4,5]
assert find_max_number(data_list, data_list[0]) == 5
# 1. 通过递归的方式实现二分查找算法。
def binary_search(data_list, low, high, target):
# 基线条件:函数不再调用自己。
if low>high:
return -1
# 基线条件:获取到中间元素,停止递归,返回中间值索引
mid = (low+high)//2
if data_list[mid] == target:
return mid
# 递归条件:目标值> 中间值
if target> data_list[mid]:
low = mid +1
# 递归条件:目标值< 中间值
else:
high= mid -1
return binary_search(data_list, low, high, target)
def test_binary_search():
assert binary_search([1,2,3,4,5,6,7,8], 5) == 4
assert binary_search([1,2,3,4,5], 1) == 0
assert binary_search([1,2,3,4,5], 9) == -1
无论是选择排序还是冒泡排序,其时间复杂度都达到了 O(n²)。不适合处理大量数据的排序。
if len(array)<2:
return array
import java.util.Arrays;
public class Sort {
// 交换逻辑
private void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 分区
private int partition(int[] arr, int low, int high) {
// 基准值
int pivot = arr[low];
// 初始化分区左边界的指针
int i = low;
// 在子数组中进行划分
for (int j = low+1; j <= high; j++) {
// 如果当前元素小于或等于基准元素,则将其交换到较小元素的位置
if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
// 将基准元素交换到较小元素的右边
swap(arr, i , low);
// 返回基准元素的索引
return i;
}
public void quickSort(int[] arr, int low, int high) {
if (arr == null || arr.length == 0) {
return;
}
if (low < high) {
// 选择一个基准元素并对数组进行划分
int pivotIndex = partition(arr, low, high);
// 对基准元素左边的子数组进行递归排序
quickSort(arr, low, pivotIndex - 1);
// 对基准元素右边的子数组进行递归排序
quickSort(arr, pivotIndex + 1, high);
}
}
}
// 测试用例
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
class SortTest {
static Sort sort;
@BeforeAll
static void setUp(){
sort = new Sort();
}
@Test
void quickSort() {
int[] arr = {5, 2, 9, 8, 1, 3, 6};
int[] arr2 = {5, 2, 9, 8, 1, 3, 6};
Arrays.sort(arr2);
sort.quickSort(arr, 0 ,arr.length-1);
assertEquals(Arrays.toString(arr), Arrays.toString(arr2));
}
}
def quick_sort(origin_list):
# 基准条件: 长度为1 或者 长度为0
if len(origin_list) == 1 or len(origin_list) == 0:
return origin_list
left = []
right = []
# 1. 遍历数组,比它大的往右边放,比它小的,往左边放。
pivot = origin_list[0]
for i in range(1, len(origin_list)):
if origin_list[i] > pivot:
right.append(origin_list[i])
elif origin_list[i]< pivot:
left.append(origin_list[i])
# 2. 递归处理左、 右数组,最后拼接。
return quick_sort(left) +[pivot]+ quick_sort(right)
def test_quick_sort():
assert quick_sort([5,4,3,2,1]) == [1,2,3,4,5]