【双机位A卷】华为OD笔试之【模拟】双机位A-螺旋数字矩阵【Py/Java/C++/C/JS/Go六种语言】【欧弟算法】全网注释最详细分类最全的华子OD真题题解

可上 欧弟OJ系统 练习华子OD、大厂真题
绿色聊天软件戳 od1441了解算法冲刺训练(备注【CSDN】否则不通过)

相关推荐阅读

题目练习网址:【模拟】双机位A-螺旋数字矩阵

题目描述与示例

题目描述

疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。

他发明了一种写法:给出数字个数n和行数m (0 < n < 999,0 < m < 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出1, 2, 3, ..., n,最终形成一个m行矩阵。

小明对这个矩阵有些要求:

  1. 每行数字的个数一样多
  2. 列的数量尽可能少
  3. 填充数字时优先填充外部
  4. 数字不够时,使用单个*号占位

输入描述

两个整数,空格隔开,依次表示nm

输出描述

符合要求的唯一短阵

示例

输入

9 4

输出

1 2 3
* * 4
9 * 5
8 7 6

解题思路

注意,本题和LeetCode54、螺旋矩阵非常类似。

本题既可以用迭代方法也可以用递归方法完成。本题解主要介绍递归方法。

题目要求矩阵列数尽可能少,使用向上取整,很容易算出来最小的列数为c = ceil(n / m)

注意到每次填充都优先填充矩阵的最外圈,比如对于5*5的矩阵,初始化均用*填充

* * * * *
* * * * *
* * * * *
* * * * *
* * * * *

假设需要填充21个数,那么第一圈会螺旋式地填充如下

1 2 3 4 5
16 * * * 6
15 * * * 7
14 * * * 8
13 12 11 10 9

中间剩余一个(5-2)*(5-2) = 3*3未填充矩阵,那么可以从17开始继续螺旋式地填充第二层矩阵,直到到达21,即

1 2 3 4 5
16 17 18 19 6
15 * * 20 7
14 * * 21 8
13 12 11 10 9

显然每一次填充,都是从未填充矩阵的左上角开始填充其外层,直到填充完毕或到达规定数字

因此可以使用递归来完成上述过程。

首先我们需要初始化一个均由"*"填充的m``*``c的二维矩阵ans

# 计算列数c,为n除以m后向上取整
c = ceil(n / m)
# 初始化答案螺旋数组,先用"*"填充
ans = [["*"] * c for _ in range(m)]

在递归过程中,我们需要

  • 四个参数start_i, end_i, start_j, end_j分别为子矩阵的起始、终止的ij下标。即
      start_j       end_j
            ↓       ↓
start_i →   * * * * *
            * * * * *
            * * * * *
            * * * * *
end_i   →   * * * * *
  • cur_num为未填充子矩阵左上角的第一个数
  • 填充结束的终止数字n

以填充子矩阵的上边界为例,我们需要固定start_i,从左往右(从start_jend_j)遍历j

在遍历过程中,我们需要把ans[start_i][j]修改为str(cur_num),同时增加cur_num,且一旦发现cur_num大于n,则可以直接退出函数。代码为

def help(ans, start_i, end_i, start_j, end_j, cur_num, n):
    pass
    # 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for j in range(start_j, end_j):
        ans[start_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    pass

同理我们可以构建出填充子矩阵其他遍历方向的代码

def help(ans, start_i, end_i, start_j, end_j, cur_num, n):
    pass
    # 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for j in range(start_j, end_j):
        ans[start_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
    for i in range(start_i, end_i):
        ans[i][end_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
    for j in range(end_j, start_j, -1):
        ans[end_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历j
    for i in range(end_i, start_i, -1):
        ans[i][start_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    pass

在所有遍历和边界填充完成之后,我们需要进行递归函数的调用。

注意到在下一层递归中,四个边界分别变成了start_i+1, end_i-1, start_j+1, end_j-1。即代码为

def help(ans, start_i, end_i, start_j, end_j, cur_num, n):
    pass
    # 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for j in range(start_j, end_j):
        ans[start_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
    for i in range(start_i, end_i):
        ans[i][end_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
    for j in range(end_j, start_j, -1):
        ans[end_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历i
    for i in range(end_i, start_i, -1):
        ans[i][start_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 对未填充数组进行递归
    # start_i, end_i, start_j, end_j需要修改
    help(ans, start_i+1, end_i-1, start_j+1, end_j-1, cur_num, n)

除此之外,还需要考虑一种特殊情况。

如果遍历区间不存在,则不会进入四个for循环中的任意一个,会持续进行递归,导致编译栈溢出。

这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现。

譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况。

我们还需要额外判断这种条件,将最中间的数字填充上并退出递归即可。修改代码为

def help(ans, start_i, end_i, start_j, end_j, cur_num, n):
    # 如果不存在遍历区间,则不会进入下面四个for循环中的任意一个
    # 会持续进行递归,导致编译栈溢出
    # 这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现
    # 譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况
    # 额外判断这种条件,将最中间的数字填充上并退出递归即可
    if start_i == end_i and start_j == end_j:
        ans[start_i][start_j] = cur_num
        return
    # 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for j in range(start_j, end_j):
        ans[start_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
    for i in range(start_i, end_i):
        ans[i][end_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
    for j in range(end_j, start_j, -1):
        ans[end_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历j
    for i in range(end_i, start_i, -1):
        ans[i][start_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 对未填充数组进行递归
    # start_i, end_i, start_j, end_j需要修改
    help(ans, start_i+1, end_i-1, start_j+1, end_j-1, cur_num, n)

剩下的内容就是递归入口的调用了。

分别对start_i, end_i, start_j, end_j传入0, m-1, 0, c-1即可。

cur_num则传入第一个需要填充的数字1。即

# 递归入口:start_i, end_i, start_j, end_j
# 分别传入0, m-1, 0, c-1
help(ans, 0, m-1, 0, c-1, 1, n)

代码

Python

# 欢迎来到「欧弟算法 - 华为OD全攻略」,收录华为OD题库、面试指南、八股文与学员案例!
# 地址:https://www.odalgo.com
# 华为OD机试刷题网站:https://www.algomooc.com
# 添加微信 278166530 获取华为 OD 笔试真题题库和视频

# 题目:【模拟】2024D/2024E/2025A/2025B/双机位A-螺旋矩阵
# 分值:100
# 作者:许老师-闭着眼睛学数理化
# 算法:模拟/递归
# 代码看不懂的地方,请直接在群上提问


from math import ceil

# 递归函数
# ans为答案螺旋矩阵
# start_i, end_i, start_j, end_j分别为子矩阵的起始、终止的i和j下标
# cur_num为未填充子矩阵左上角的第一个数
# n为终止数字
def help(ans, start_i, end_i, start_j, end_j, cur_num, n):
    # 如果不存在遍历区间,则不会进入下面四个for循环中的任意一个
    # 会持续进行递归,导致编译栈溢出
    # 这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现
    # 譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况
    # 额外判断这种条件,将最中间的数字填充上并退出递归即可
    if start_i == end_i and start_j == end_j:
        ans[start_i][start_j] = cur_num
        return
    # 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for j in range(start_j, end_j):
        ans[start_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
    for i in range(start_i, end_i):
        ans[i][end_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
    for j in range(end_j, start_j, -1):
        ans[end_i][j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历j
    for i in range(end_i, start_i, -1):
        ans[i][start_j] = str(cur_num)
        cur_num += 1
        if cur_num > n: return
    # 对未填充数组进行递归
    # start_i, end_i, start_j, end_j需要修改
    help(ans, start_i+1, end_i-1, start_j+1, end_j-1, cur_num, n)

# 输入数字n,行数m
n, m = map(int, input().split())
# 计算列数c,为n除以m后向上取整
c = ceil(n / m)

# 初始化答案螺旋数组,先用"*"填充
ans = [["*"] * c for _ in range(m)]

# 递归入口:start_i, end_i, start_j, end_j
# 分别传入0, m-1, 0, c-1
help(ans, 0, m-1, 0, c-1, 1, n)
# 逐行输出螺旋矩阵
for row in ans:
    print(*row)

Java

import java.util.Scanner;

public class Main {
    // 递归函数
    // ans为答案螺旋矩阵
    // start_i, end_i, start_j, end_j分别为子矩阵的起始、终止的i和j下标
    // cur_num为未填充子矩阵左上角的第一个数
    // n为终止数字
    static void help(String[][] ans, int start_i, int end_i, int start_j, int end_j, int cur_num, int n) {
        // 如果不存在遍历区间,则不会进入下面四个for循环中的任意一个
        // 会持续进行递归,导致编译栈溢出
        // 这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现
        // 譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况
        // 额外判断这种条件,将最中间的数字填充上并退出递归即可
        if (start_i == end_i && start_j == end_j) {
            ans[start_i][start_j] = String.valueOf(cur_num);
            return;
        }
        // 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
        for (int j = start_j; j <= end_j; j++) {
            ans[start_i][j] = String.valueOf(cur_num++);
            if (cur_num > n) return;
        }
        // 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
        for (int i = start_i + 1; i <= end_i; i++) {
            ans[i][end_j] = String.valueOf(cur_num++);
            if (cur_num > n) return;
        }
        // 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
        for (int j = end_j - 1; j >= start_j; j--) {
            ans[end_i][j] = String.valueOf(cur_num++);
            if (cur_num > n) return;
        }
        // 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历i
        for (int i = end_i - 1; i > start_i; i--) {
            ans[i][start_j] = String.valueOf(cur_num++);
            if (cur_num > n) return;
        }
        // 对未填充数组进行递归
        // start_i, end_i, start_j, end_j需要修改
        help(ans, start_i + 1, end_i - 1, start_j + 1, end_j - 1, cur_num, n);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 输入数字n,行数m
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        // 计算列数c,n除以m后向上取整
        int c = (int) Math.ceil((double) n / m);

        // 初始化答案螺旋数组,先用"*"填充
        String[][] ans = new String[m][c];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < c; j++) {
                ans[i][j] = "*";
            }
        }

        // 递归入口:start_i, end_i, start_j, end_j
        // 分别传入0, m-1, 0, c-1
        help(ans, 0, m - 1, 0, c - 1, 1, n);
        // 逐行输出螺旋矩阵
        for (String[] row : ans) {
            System.out.println(String.join(" ", row));
        }
    }
}

C++

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

// 递归函数
// ans为答案螺旋矩阵
// start_i, end_i, start_j, end_j分别为子矩阵的起始、终止的i和j下标
// cur_num为未填充子矩阵左上角的第一个数
// n为终止数字
void help(vector<vector<string>>& ans, int start_i, int end_i, int start_j, int end_j, int& cur_num, int n) {
    // 如果不存在遍历区间,则不会进入下面四个for循环中的任意一个
    // 会持续进行递归,导致编译栈溢出
    // 这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现
    // 譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况
    // 额外判断这种条件,将最中间的数字填充上并退出递归即可
    if (start_i == end_i && start_j == end_j) {
        ans[start_i][start_j] = to_string(cur_num);
        return;
    }
    // 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for (int j = start_j; j <= end_j; j++) {
        ans[start_i][j] = to_string(cur_num++);
        if (cur_num > n) return;
    }
    // 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
    for (int i = start_i + 1; i <= end_i; i++) {
        ans[i][end_j] = to_string(cur_num++);
        if (cur_num > n) return;
    }
    // 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
    for (int j = end_j - 1; j >= start_j; j--) {
        ans[end_i][j] = to_string(cur_num++);
        if (cur_num > n) return;
    }
    // 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历i
    for (int i = end_i - 1; i > start_i; i--) {
        ans[i][start_j] = to_string(cur_num++);
        if (cur_num > n) return;
    }
    // 对未填充数组进行递归
    // start_i, end_i, start_j, end_j需要修改
    help(ans, start_i + 1, end_i - 1, start_j + 1, end_j - 1, cur_num, n);
}

int main() {
    // 输入数字n,行数m
    int n, m;
    cin >> n >> m;
    // 计算列数c,n除以m后向上取整
    int c = ceil(static_cast<double>(n) / m);

    // 初始化答案螺旋数组,先用"*"填充
    vector<vector<string>> ans(m, vector<string>(c, "*"));

    int cur_num = 1;
    // 递归入口:start_i, end_i, start_j, end_j
    // 分别传入0, m-1, 0, c-1
    help(ans, 0, m - 1, 0, c - 1, cur_num, n);
    // 逐行输出螺旋矩阵
    for (const auto& row : ans) {
        for (const auto& elem : row) {
            cout << elem << " ";
        }
        cout << endl;
    }

    return 0;
}

C

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// 递归函数
// ans为答案螺旋矩阵
// start_i, end_i, start_j, end_j分别为子矩阵的起始、终止的i和j下标
// cur_num为未填充子矩阵左上角的第一个数
// n为终止数字
void fillSpiral(int **ans, int start_i, int end_i, int start_j, int end_j, int *cur_num, int n) {
    // 如果不存在遍历区间,则不会进入下面四个for循环中的任意一个
    // 会持续进行递归,导致编译栈溢出
    // 这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现
    // 譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况
    // 额外判断这种条件,将最中间的数字填充上并退出递归即可
    if (start_i == end_i && start_j == end_j) {
        ans[start_i][start_j] = *cur_num;
        return;
    }
    // 未填充矩阵的上边界:从左往右,固定start_i,正序遍历j
    for (int j = start_j; j < end_j; j++) {
        ans[start_i][j] = (*cur_num)++;
        if (*cur_num > n) return;
    }
    // 未填充矩阵的右边界:从上往下,固定end_j,正序遍历i
    for (int i = start_i; i < end_i; i++) {
        ans[i][end_j] = (*cur_num)++;
        if (*cur_num > n) return;
    }
    // 未填充矩阵的下边界:从右往左,固定end_i,逆序遍历j
    for (int j = end_j; j > start_j; j--) {
        ans[end_i][j] = (*cur_num)++;
        if (*cur_num > n) return;
    }
    // 未填充矩阵的左边界:从下往上,固定start_j,逆序遍历i
    for (int i = end_i; i > start_i; i--) {
        ans[i][start_j] = (*cur_num)++;
        if (*cur_num > n) return;
    }
    // 对未填充数组进行递归
    // start_i, end_i, start_j, end_j需要修改
    fillSpiral(ans, start_i + 1, end_i - 1, start_j + 1, end_j - 1, cur_num, n);
}

int main() {
    int n, m;
    // 输入数字n,行数m
    scanf("%d %d", &n, &m);
    // 计算列数c,n除以m后向上取整
    int c = (int)ceil((double)n / m);

    // 初始化答案螺旋数组,先用0填充
    int **ans = (int **)malloc(m * sizeof(int *));
    for (int i = 0; i < m; i++) {
        ans[i] = (int *)malloc(c * sizeof(int));
        for (int j = 0; j < c; j++) {
            ans[i][j] = 0;
        }
    }

    int cur_num = 1;
    // 递归入口:start_i, end_i, start_j, end_j
    // 分别传入0, m-1, 0, c-1
    fillSpiral(ans, 0, m - 1, 0, c - 1, &cur_num, n);

    // 逐行输出螺旋矩阵
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < c; j++) {
            if (ans[i][j] == 0) {
                printf("*");
            } else {
                printf("%d", ans[i][j]);
            }
            if (j < c - 1) {
                printf(" ");
            }
        }
        printf("\n");
    }

    // 释放内存
    for (int i = 0; i < m; i++) {
        free(ans[i]);
    }
    free(ans);

    return 0;
}

Node JavaScript

const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

rl.question('', (input) => {
    const [n, m] = input.split(' ').map(Number);
    const c = Math.ceil(n / m);

    // 初始化答案螺旋数组,先用""填充
*    const ans = Array.from({ length: m }, () => Array(c).fill("*"));

    // 递归函数
    function help(start_i, end_i, start_j, end_j, cur_num) {
        if (start_i === end_i && start_j === end_j) {
            ans[start_i][start_j] = cur_num.toString();
            return;
        }
        // 上边界
        for (let j = start_j; j < end_j; j++) {
            ans[start_i][j] = cur_num.toString();
            cur_num++;
            if (cur_num > n) return;
        }
        // 右边界
        for (let i = start_i; i < end_i; i++) {
            ans[i][end_j] = cur_num.toString();
            cur_num++;
            if (cur_num > n) return;
        }
        // 下边界
        for (let j = end_j; j > start_j; j--) {
            ans[end_i][j] = cur_num.toString();
            cur_num++;
            if (cur_num > n) return;
        }
        // 左边界
        for (let i = end_i; i > start_i; i--) {
            ans[i][start_j] = cur_num.toString();
            cur_num++;
            if (cur_num > n) return;
        }
        // 递归处理内部子矩阵
        help(start_i + 1, end_i - 1, start_j + 1, end_j - 1, cur_num);
    }

    // 初始化递归
    help(0, m - 1, 0, c - 1, 1);

    // 输出结果
    ans.forEach(row => console.log(row.join(' ')));
    rl.close();
});

Go

package main

import (
        "fmt"
        "math"
        "strconv"
)

// 递归函数
// ans为答案螺旋矩阵
// start_i, end_i, start_j, end_j分别为子矩阵的起始、终止的i和j下标
// curNum为未填充子矩阵左上角的第一个数
// n为终止数字
func fillSpiral(ans [][]string, startI, endI, startJ, endJ, curNum, n int) {
        // 如果不存在遍历区间,则不会进入下面四个for循环中的任意一个
        // 会持续进行递归,导致编译栈溢出
        // 这种情况就是当n为某个奇数的平方且c = m = sqrt(n)的时候会出现
        // 譬如填充5*5的矩阵且n = 25,最中间那个数字会出现的情况
        // 额外判断这种条件,将最中间的数字填充上并退出递归即可
        if startI == endI && startJ == endJ {
                ans[startI][startJ] = strconv.Itoa(curNum)
                return
        }
        // 未填充矩阵的上边界:从左往右,固定startI,正序遍历j
        for j := startJ; j < endJ; j++ {
                ans[startI][j] = strconv.Itoa(curNum)
                curNum++
                if curNum > n {
                        return
                }
        }
        // 未填充矩阵的右边界:从上往下,固定endJ,正序遍历i
        for i := startI; i < endI; i++ {
                ans[i][endJ] = strconv.Itoa(curNum)
                curNum++
                if curNum > n {
                        return
                }
        }
        // 未填充矩阵的下边界:从右往左,固定endI,逆序遍历j
        for j := endJ; j > startJ; j-- {
                ans[endI][j] = strconv.Itoa(curNum)
                curNum++
                if curNum > n {
                        return
                }
        }
        // 未填充矩阵的左边界:从下往上,固定startJ,逆序遍历i
        for i := endI; i > startI; i-- {
                ans[i][startJ] = strconv.Itoa(curNum)
                curNum++
                if curNum > n {
                        return
                }
        }
        // 对未填充数组进行递归
        // startI, endI, startJ, endJ需要修改
        fillSpiral(ans, startI+1, endI-1, startJ+1, endJ-1, curNum, n)
}

func main() {
        // 输入数字n,行数m
        var n, m int
        fmt.Scan(&n, &m)
        // 计算列数c,n除以m后向上取整
        c := int(math.Ceil(float64(n) / float64(m)))

        // 初始化答案螺旋数组,先用"*"填充
        ans := make([][]string, m)
        for i := range ans {
                ans[i] = make([]string, c)
                for j := range ans[i] {
                        ans[i][j] = "*"
                }
        }

        // 递归入口:startI, endI, startJ, endJ
        // 分别传入0, m-1, 0, c-1
        curNum := 1
        fillSpiral(ans, 0, m-1, 0, c-1, curNum, n)

        // 逐行输出螺旋矩阵
        for _, row := range ans {
                for j, elem := range row {
                        if j > 0 {
                                fmt.Print(" ")
                        }
                        fmt.Print(elem)
                }
                fmt.Println()
        }
}

时空复杂度

时间复杂度:O(N)。需要填充N个数字。

空间复杂度:O(MC)。忽略递归所需要的编译栈空间,需要构建大小为c*m的二维矩阵ans


华为OD算法/大厂面试高频题算法练习冲刺训练

  • 华子OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务1000+同学成功上岸!

  • 课程讲师为全网200w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化

  • 90+天陪伴式学习,100+直播课时,300+动画图解视频,500+LeetCode经典题,500+华为OD真题/大厂真题,还有简历修改、模拟面试、陪伴小群、资深HR对接将为你解锁

  • 可上全网独家的欧弟OJ系统练习华子OD、大厂真题

  • 可查看链接OD真题汇总(持续更新)

  • 绿色聊天软件戳 od1441或了解更多

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闭着眼睛学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值