牛客网 - 华为OD算法机试(可内推)
Posted code tea
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客网 - 华为OD算法机试(可内推)相关的知识,希望对你有一定的参考价值。
1.前言
这几天在闭关修炼数据结构和算法, 也好几天没有更新博客了。
其实我也没学多久的算法, 满打满算牛客和leecode也就刷了四十来道题。
其实算法也没有我们一开始想象的那么难, 至少面试考的算法都还比较基础。
今天参加了华为OD的机试, 没有想象中的那么难, 但是还是熟练度的问题, 加上第一次考试有点紧张。前两题过了100%的用例, 用时一小时, 后面一个半小时都在刚第三题, 结果自己对递归的返回值处理不到位, 相当于没过吧, 晚上抽时间把代码调整了下, 应该是能正常跑过了。
现在把我经历的三道题分享出来, 有兴趣或者有建议的大佬的可以在我的博客留言。
建议看完题意后先自己思考怎么实现
本文题解只能实现功能, 并不是最优算法
ps: 一面 / 二面 也结束了, 我做了一些总结, 有兴趣可以看我这篇博客
华为od一面 / 二面复盘
第一题: 求剩余扑克牌最大顺子问题 100分
题意
扑克牌为 345678910JQKA 每种牌4张
输入是你现在的手牌, 还有已经打出去的牌
求剩下的牌中能凑出来的最大的顺子是多少
这里顺子的大小优先比较长度, 相同长度的顺子则比较牌面大小
比如:
你的手牌 3-3-3-8-8-8-8
已经打出的牌 4-4-5-5-6-6
最大的顺子是 9-10-J-Q-K-A
题解
import java.util.*;
public class Main
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
//手牌
String s1 = sc.nextLine();
//出过的牌
String s2 = sc.nextLine();
//初始化
HashMap<String, Integer> count = new HashMap<>(16);
for (int i = 3; i <= 10; i++)
count.put(String.valueOf(i), 4);
count.put("J", 4);
count.put("Q", 4);
count.put("K", 4);
count.put("A", 4);
String[] ss1 = s1.split("-");
for (int i = 0; i < ss1.length; i++)
count.put(ss1[i], count.get(ss1[i]) - 1);
String[] ss2 = s2.split("-");
for (int i = 0; i < ss2.length; i++)
count.put(ss2[i], count.get(ss2[i]) - 1);
//最大长度,队列, 读到0就输出前面的串
String[] sa = new String[]"3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A";
Deque<String> list = new LinkedList<>();
//从大的开始
String result = null;
int max = 0;
for (int i = sa.length - 1; i >= 0; i--)
if (count.get(sa[i]) > 0)
list.offerFirst(sa[i]);
else
//读到0了, 看能不能组成顺子
if (list.size() < 5)
list.clear();
else
if (list.size() > max)
max = list.size();
String tem = "";
while (list.size() > 0)
tem += list.pollFirst() + "-";
result = tem.substring(0, tem.length() - 1);
else
list.clear();
//读到头 处理剩余数据
if (list.size() >= 5 && list.size() > max)
max = list.size();
String tem = "";
while (list.size() > 0)
tem += list.pollFirst() + "-";
result = tem.substring(0, tem.length() - 1);
if (max == 0)
System.out.println("NO-CHAIN");
else
System.out.println(result);
第二题: 一系列正整数, 从中取三个数拼接后的最小数字 100分
题意
给你一系列数字, 从中取出三个数字, 如果给的数字不到三个有几个取几个
求这几个数字拼接后的最小数字是多少。
比如:
给定 18,123,22,5,12,34,23,43,344,21
拼接后的最小数字是 12,18,5的拼接, 12185
这道题比较简单, 注意边界条件的处理, 而且数字可能超长
题解
import java.math.BigDecimal;
import java.util.*;
public class Main2
static BigDecimal min;
static String[] choice = new String[3];
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String[] ss = s.split(",");
if (ss.length == 0)
System.out.println(0);
return;
else if (ss.length == 1)
System.out.println(ss[0]);
return;
else if (ss.length == 2)
System.out.println(Math.min(Integer.parseInt(ss[0] + ss[1]),
Integer.parseInt(ss[1] + ss[0])));
return;
//数组长度为3及以上,取三个长度最短的, 相等的都取出来
//截取0后长度最短的
PriorityQueue<String> queue = new PriorityQueue<>(new Comparator<String>()
@Override
public int compare(String o1, String o2)
return new BigDecimal(o1).compareTo(new BigDecimal(o2));
);
for (int i = 0; i < ss.length; i++)
queue.offer(ss[i]);
choice[0] = queue.poll();
choice[1] = queue.poll();
choice[2] = queue.poll();
//最小数字
min = new BigDecimal(choice[0] + choice[1] + choice[2]);
int[] ids = new int[3];
for (int i = 0; i < 3; i++)
int[] idsCopy = Arrays.copyOf(ids, ids.length);
idsCopy[i] = 1;
build(idsCopy, 0, i, "");
System.out.println(min);
public static void build(int[] ids, int count, int index, String s)
s += choice[index];
if (count == 2)
BigDecimal bigDecimal = new BigDecimal(s);
if (bigDecimal.compareTo(min) < 0)
min = bigDecimal;
return;
for (int i = 0; i < 3; i++)
int[] idsCopy = Arrays.copyOf(ids, ids.length);
if (idsCopy[i] != 1)
idsCopy[i] = 1;
build(idsCopy, count + 1, i, s);
第三题: 两人野营, 求两人能共同到达的聚餐点数量
题意
给定一个m*n的矩阵, 矩阵中数字 0 代表空地, 可通过, 1 代表障碍, 不可通过, 数字 2 代表两个人所在的位置, 3代表聚餐点所在的位置。
求两个人同时能够到达的聚餐点有多少个?
比如:
给定, 第一行的两个数字分别是m, n
4 4
2 1 0 3
0 1 2 1
0 3 0 0
0 0 0 0
求得 2
题解
public class Main3
public static void main(String[] args)
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String[] ss = s.split(" ");
//长
m = Integer.parseInt(ss[0]);
//宽
n = Integer.parseInt(ss[1]);
List<Pos> eatPos = new ArrayList<>();
int[][] serched = new int[m][n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
int point = sc.nextInt();
if (point == 3)
eatPos.add(new Pos(i, j));
if (point == 1)
serched[i][j] = 1;
arr[i][j] = point;
if (eatPos.size() == 0)
System.out.println(0);
return;
for (Pos eat : eatPos)
//从聚餐点可以到达几个人, 如果能到达两个人, 则可达聚餐点+1
int personFlag = 0;
Pos left = eat.left();
Pos right = eat.right();
Pos up = eat.up();
Pos down = eat.down();
serched[eat.x][eat.y] = 1;
//上下左右
personFlag = search(left.x, left.y, personFlag, serched);
if (personFlag == 2)
result++;
continue;
personFlag = search(right.x, right.y, personFlag, serched);
if (personFlag == 2)
result++;
continue;
personFlag = search(up.x, up.y, personFlag, serched);
if (personFlag == 2)
result++;
continue;
personFlag = search(down.x, down.y, personFlag, serched);
if (personFlag == 2)
result++;
System.out.println(result);
static int m;
static int n;
static int result = 0;
static int[][] arr = new int[99][99];
/**
* @param x 找的下一个点
* @param y 找的下一个点
* @param personFlag 记录已经找到的人数, 找到2个人就成功, 给答案+1
* @param searched 记录已经找过的点
*/
public static int search(int x, int y, int personFlag, int[][] searched)
if (!isValid(x, y, searched))
return personFlag;
if (arr[x][y] == 2)
personFlag++;
if (personFlag == 2)
return personFlag;
int[][] serchedCopy = new int[m][n];
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
serchedCopy[i][j] = searched[i][j];
serchedCopy[x][y] = 1;
Pos current = new Pos(x, y);
Pos left = current.left();
Pos right = current.right();
Pos up = current.up();
Pos down = current.down();
//上下左右
personFlag = search(left.x, left.y, personFlag, serchedCopy);
if (personFlag == 2)
return personFlag;
personFlag = search(right.x, right.y, personFlag, serchedCopy);
if (personFlag == 2)
return personFlag;
personFlag = search(up.x, up.y, personFlag, serchedCopy);
if (personFlag == 2)
return personFlag;
personFlag = search(down.x, down.y, personFlag, serchedCopy);
return personFlag;
/**
* 是否在边界内而且没找过
*/
public static boolean isValid(int x, int y, int[][] searched)
if (x >= m || x < 0 || y >= n || y < 0)
return false最近更新的博客
华为OD机试 - 自动曝光(Python) | 机试题算法思路 【2023】
华为OD机试 - 双十一(Python) | 机试题算法思路 【2023】
华为OD机试 - 删除最少字符(Python) | 机试题算法思路 【2023-02】
华为OD机试 - Excel 单元格数值统计(Python) | 机试题算法思路 【2023】
华为OD机试 -旋转骰子(Python) | 机试题算法思路 【2023】
使用说明
参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。
华为 OD 清单查看地址:blog.csdn.net/hihell/category_12199275.html
华为OD详细说明:
以上是关于牛客网 - 华为OD算法机试(可内推)的主要内容,如果未能解决你的问题,请参考以下文章