华为机试9.1(通信/射频算法岗)
从7月份开始围观牛客大佬们的面经,收获很大。昨天考完机试,记录一下题目。
第一题:模糊搜索【不会&没时间做】
输入描述:
第一行是搜索词,第二行是目标文本,包含了多个目标词的一行文本。
输入的约束:1.搜索词和目标词是一个单词 2.单词定义:长度为[0,100]之间的字符串,仅有大写字母,小写字母,数字和中横线-组成。
第一题把样例中的答案输出一个能过5%
第2题:BFS求最短路径问题
题目描述:
小明从矩阵的左上角开始走到矩阵右下角所需要的最小的次数。
矩阵:有0和1组成,1是陆地(可以走路的)0是水面(不能走路的)
其他条件:(1)每次可以从上下左右四个方向走(2)小明每次走路喜欢1 2 1 2 1 2...交替走:即第一次走1步,第2次走2步,第3次走1步,第4次走2步...
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* @Description
* 思路:从起点到终点
* 1.BFS
* 2.加一个判断当前层数的变量count:
* 若count为奇数:走一步
* 若count为偶数,走两步
*/
public class Main {
//走一步
private static int[][] Direction1 = new int[][]{{-1,0},{0,1},{1,0},{0,-1}};
//走两步
private static int[][] Direction2 = new int[][]{{-2,0},{0,2},{2,0},{0,-2}};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int M = sc.nextInt();//写入矩阵的行
int N = sc.nextInt();//写入矩阵的列
int[][] nums = new int[M][N];
for(int i=0;i<M;i++){
for(int j=0;j<N;j++){
nums[i][j] = sc.nextInt();//输入矩阵
}
}
int res = solution(nums);
System.out.println(res);
}
public static int solution(int[][] nums){
int row = nums.length;
int col = nums[0].length;
boolean[][] visited = new boolean[row][col];
Queue<int[]> queue = new LinkedList<>();//队列来记录矩阵的索引,有数组表示[i,j]
queue.offer(new int[]{0,0});//队列的初始化,将起点(0,0)放进去
int count=0;//记录层数
while(!queue.isEmpty()){
int size = queue.size();
count ++;
for(int i=0;i<size;i++){
int[] tmp = queue.poll();
//count为奇数时,走一步
if(count % 2 != 0){
for(int[] edge : Direction1){
int newx = edge[0] + tmp[0];
int newy = edge[1] + tmp[1];
if(isValid(newx,newy,nums) && !visited[newx][newy] && nums[newx][newy] == 1){
if(newx == row-1 && newy == col-1){
return count;
}
visited[newx][newy] = true;
queue.offer(new int[]{newx,newy});
}
}
}
//count为奇数时,走一步
if(count % 2 == 0){
for(int[] edge : Direction2){
int newx = edge[0] + tmp[0];
int newy = edge[1] + tmp[1];
if(isValid(newx,newy,nums) && !visited[newx][newy] && nums[newx][newy] == 1){
if(newx == row-1 && newy == col-1){
return count;
}
visited[newx][newy] = true;
queue.offer(new int[]{newx,newy});
}
}
}
}
}
return 0;
}
static boolean isValid(int i,int j,int[][] nums){
int row = nums.length;
int col = nums[0].length;
if(i<0 || i>=row || j<0 || j>=col) return false;
else return true;
}
}
//这种写法过了75%,不知道哪里出了问题🤤
第三题:给了一大堆文字描述,提炼出来,就是求一个无向图有几个连通分量的问题,力扣上这种题很多。DFS就能100% import java.util.*; /** * @Description 求连通的个数 * 输入描述: * 第一个数为顶点与顶点之间的连接关系数N * 接下来输入N行,表示两顶点之间相连 * * 输出:有几个连通图 * * 输入: * 6 * [0 1] * [0 2] * [0 3] * [0 4] * [4 5] * [6 7] * * 输出: * 2 * //不知道顶点个数,而且顶点是无序的,并非为0~n-1这样的, * 所以构造图时采用HashMap,同时记录顶点和对应的邻接表 * @creat 2021-09-01 */ public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); HashMap<Integer, Set<Integer>> adj = new HashMap<>(); HashMap<Integer, Boolean> visited = new HashMap<>();//标记顶点是否被访问 //构建无向图 //1.构建顶点: Set<Integer> set = new HashSet<>();//去重操作 List<Integer> list = new LinkedList<>();//存放顶点的list int[][] edges = new int[N][2];//获取输入数据 for(int i=0;i<N;i++){ edges[i][0] = sc.nextInt(); edges[i][1] = sc.nextInt(); if(!set.contains(edges[i][0])){ list.add(edges[i][0]); set.add(edges[i][0]); } if(!set.contains(edges[i][1])){ list.add(edges[i][1]); set.add(edges[i][1]); } } //对每个顶点构建邻接表(初始化): for(Integer g : list){ adj.put(g,new HashSet<>()); visited.put(g,false); } //添加顶点间的指向 for(int[] edge : edges){ adj.get(edge[0]).add(edge[1]); adj.get(edge[1]).add(edge[0]); } //对每个顶点进行DFS遍历 //访问当前节点标记为true int count=0;//记录连通图数量 for(Integer i : list){ if(!visited.get(i)){ dfs(i,adj,visited); count++; } } System.out.println(count); } static void dfs(int i, HashMap<Integer, Set<Integer>> adj ,HashMap<Integer, Boolean> visited){ visited.put(i,true); Set<Integer> temp = adj.get(i);//当前顶点的邻接表 for(Integer g : temp){ if(!visited.get(g)){ dfs(g,adj,visited); } } } }
PS:通信/射频算法机试题确实比软开的简单😅